获取元素的 jQuery 选择器

IT技术 javascript jquery jquery-selectors
2021-02-09 05:09:48

在伪代码中,这就是我想要的。

var selector = $(this).cssSelectorAsString(); // Made up method...
// selector is now something like: "html>body>ul>li>img[3]"
var element = $(selector);

原因是我需要将其传递给外部环境,其中字符串是我交换数据的唯一方式。然后这个外部环境需要发回一个结果,以及要更新的元素。所以我需要能够为页面上的每个元素序列化一个唯一的 CSS 选择器。

我注意到 jquery 有一个selector方法,但它在这种情况下似乎不起作用。仅当对象是使用选择器创建时才有效。如果对象是使用 HTML 节点对象创建的,则它不起作用。

6个回答

我现在看到存在一个插件(我也想到了同名),但这里只是我写的一些快速 JavaScript。它不考虑元素的 id 或类——只考虑结构(并添加:eq(x)节点名称不明确的地方)。

jQuery.fn.getPath = function () {
    if (this.length != 1) throw 'Requires one element.';

    var path, node = this;
    while (node.length) {
        var realNode = node[0], name = realNode.name;
        if (!name) break;
        name = name.toLowerCase();

        var parent = node.parent();

        var siblings = parent.children(name);
        if (siblings.length > 1) { 
            name += ':eq(' + siblings.index(realNode) + ')';
        }

        path = name + (path ? '>' + path : '');
        node = parent;
    }

    return path;
};

(执照:麻省理工学院)

@Dan:啊,我感觉会有这样的东西,谢谢=)
2021-03-18 05:09:48
+1 不错的解决方案。我已经制作了一个使用多个 jQuery 元素的解决方案。但实际上没有你最新的改进。也许我会很快更新它。看我的回答...
2021-03-24 05:09:48
@algorhythm:这就是您应该使用库的原因:问题比看起来更复杂。一个这样的库明确地检查 id 确实是唯一的
2021-04-03 05:09:48
我不确定使用idif found的解决方案是否更好。我知道 anid必须是唯一的,但我看到了很多HTML程序员没有注意到的代码,并且使用了 sameid的多线程时间。而且我也知道,在不同的浏览器中,它的jQuery行为与 not uniqueid不同。你怎么认为?
2021-04-06 05:09:48
jQuery 有一个内置index函数可以处理循环部分。只是说var i = siblings.index(node),那应该有效。
2021-04-12 05:09:48

TL;DR - 这是一个比看起来更复杂的问题,您应该使用library


这个问题乍一看似乎很容易,但它比看起来更棘手,就像用链接替换普通 URL 是非平凡的一样一些考虑:

进一步证明问题并不像看起来那么简单:有 10 多个库可以生成 CSS 选择器,其中之一的作者发表了这个比较

jQuery-GetPath是一个很好的起点:它将为您提供项目的祖先,如下所示:

var path = $('#foo').getPath();
// e.g., "html > body > div#bar > ul#abc.def.ghi > li#foo"
jQuery-GetPath 不在 Github 上,而且显然自 2011 年以来就没有维护过。有 10 多个生成 CSS 选择器的合法库,其中一个的作者发布了这个比较
2021-03-20 05:09:48
最受好评的解决方案对我来说返回了“未定义”,所以这个小函数效果更好!
2021-03-20 05:09:48

这是适用于 IE 的 Blixt 答案的一个版本:

jQuery.fn.getPath = function () {
    if (this.length != 1) throw 'Requires one element.';

    var path, node = this;
    while (node.length) {
        var realNode = node[0];
        var name = (

            // IE9 and non-IE
            realNode.localName ||

            // IE <= 8
            realNode.tagName ||
            realNode.nodeName

        );

        // on IE8, nodeName is '#document' at the top level, but we don't need that
        if (!name || name == '#document') break;

        name = name.toLowerCase();
        if (realNode.id) {
            // As soon as an id is found, there's no need to specify more.
            return name + '#' + realNode.id + (path ? '>' + path : '');
        } else if (realNode.className) {
            name += '.' + realNode.className.split(/\s+/).join('.');
        }

        var parent = node.parent(), siblings = parent.children(name);
        if (siblings.length > 1) name += ':eq(' + siblings.index(node) + ')';
        path = name + (path ? '>' + path : '');

        node = parent;
    }

    return path;
};
这个问题看似简单,但实际上要复杂一些——生成独特的 CSS 选择器,理想情况下,这些选择器对页面结构的变化具有一定的鲁棒性。有 10 多个库可以生成 CSS 选择器,其中之一的作者发布了这个比较
2021-04-14 05:09:48

我也只是想分享我的版本,因为它很容易理解。我在所有常见的浏览器中测试了这个脚本,它像老板一样工作。

jQuery.fn.getPath = function () {
    var current = $(this);
    var path = new Array();
    var realpath = "BODY";
    while ($(current).prop("tagName") != "BODY") {
        var index = $(current).parent().find($(current).prop("tagName")).index($(current));
        var name = $(current).prop("tagName");
        var selector = " " + name + ":eq(" + index + ") ";
        path.push(selector);
        current = $(current).parent();
    }
    while (path.length != 0) {
        realpath += path.pop();
    }
    return realpath;
}
不使用 ids 的选择器是脆弱的
2021-03-27 05:09:48