获取元素的jQuery选择器

Ale*_*yne 45 javascript jquery jquery-selectors

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

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

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

我注意到jquery有一个selector方法,但它似乎不适用于此上下文.它仅在使用选择器创建对象时才有效.如果使用HTML节点对象创建对象,则它不起作用.

Bli*_*ixt 54

我现在看到一个插件存在(我也想到了同名),但这里只是我编写的一些快速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.localName;
        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;
};
Run Code Online (Sandbox Code Playgroud)

  • 我不确定如果找到了使用 `id` 的解决方案是否更好。我知道`id` 必须是唯一的,但是我看到了很多`HTML` 代码,而程序员没有注意到这一点,并且使用了相同的`id` 多次使用。而且我也知道,在不同的浏览器中,`jQuery` 的行为是不同的,因为 `id` 不是唯一的。你怎么认为? (2认同)

Dan*_*scu 17

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


乍一看这个问题看起来很简单,但它比看起来更棘手,就像用链接替换普通URL一样非常重要.一些考虑:

进一步证明问题并不像看起来那么容易:有10多个库生成CSS选择器,其中一个的作者发布了这个比较.


Ago*_*gos 8

jQuery-GetPath是一个很好的起点:它会给你项目的祖先,像这样:

var path = $('#foo').getPath();
// e.g., "html > body > div#bar > ul#abc.def.ghi > li#foo"
Run Code Online (Sandbox Code Playgroud)

  • jQuery-GetPath 不在 Github 上,而且显然自 2011 年以来就没有维护过。有 10 多个合法的库可以生成 CSS 选择器,其中之一的作者已经发布了[这个比较](https://github.com)。 com/fczbkk/css-selector-generator-benchmark)。 (3认同)

cri*_*aig 7

这是Blixt的一个版本在IE中的作用:

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;
};
Run Code Online (Sandbox Code Playgroud)


Ahm*_*ven 5

我只是想分享我的版本,因为它很清楚.我在所有常见浏览器中测试了这个脚本,它就像老板一样工作.

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;
}
Run Code Online (Sandbox Code Playgroud)