Javascript 如何从给定的DOM对象获取完整的css选择器字符串

Javascript 如何从给定的DOM对象获取完整的css选择器字符串,javascript,dom,Javascript,Dom,我想写一个函数 function f (domEl){ //some code here //returns a string } 以便: $(f(domEl))[0] == domEl 当然,无论domEl的层次结构是什么,都应该始终返回true: 例如,让我们说: HTML body ul li **li** li ul

我想写一个函数

function f (domEl){
    //some code here

    //returns a string
}
以便:

$(f(domEl))[0] == domEl
当然,无论domEl的层次结构是什么,都应该始终返回true:

例如,让我们说:

HTML
    body
        ul
            li
            **li**
            li
                ul
                    li
我想选择粗体的li元素。我获取该元素并将其传递到函数f中。

演示:

对于我在示例中使用的代码,选择器如下所示

演示:

对于我在示例中使用的代码,选择器如下所示


这对我来说没什么意义。domEl是否为HtmleElement类型,即从document.getElementById返回的类型?这对我来说都没有意义,但它是作为一个面试问题提出的。但是,从DOM元素中获取css选择器字符串可能很有用。是错误的HTML标记。他总是在他的领导下。那么,这三个元素是如何连续出现的呢?这与层次结构无关,$返回一个特殊的jquery对象,而标准javascript返回标准的HtmlXelement类型。如果您将domeElement传递到$,它会将其转换为JQuery对象。要求$domEl==fdomEl更有意义,除非他们希望您更改JQuery源代码。@gideon:在这段代码中,$表示JQuery?这对我来说没有太多意义。domEl是否为HtmleElement类型,即从document.getElementById返回的类型?这对我来说都没有意义,但它是作为一个面试问题提出的。但是,从DOM元素中获取css选择器字符串可能很有用。是错误的HTML标记。他总是在他的领导下。那么,这三个元素是如何连续出现的呢?这与层次结构无关,$返回一个特殊的jquery对象,而标准javascript返回标准的HtmlXelement类型。如果您将domeElement传递到$,它会将其转换为JQuery对象。要求$domEl==fdomEl更有意义,除非他们希望您更改JQuery源代码。@gideon:在这段代码中,$意味着JQuery?很抱歉,这确实是一个聪明的java脚本,但它并不适用于所有情况,请看这里:@hrishikeshp19:它为每个元素构建了第n个子选择器。它在正文处停止,假设您真的不需要再进一步了。@hrishikeshp19:这简化了选择器,因此它只在有前面的元素时使用:n子元素,结果是一个更干净的选择器BODY>DIV>DIV>UL>LI:nth-child2>UL>LI:nth-child5.@hrishikeshp19:这增加了一个优化,如果元素有一个ID属性,它只返回一个ID选择器,因为ID在页面上必须是唯一的。很抱歉,这确实是一个聪明的java脚本,但它并不适用于所有情况,请看这里:@hrishikeshp19:它为向上的每个元素构建第n个子选择器。它在正文处停止,假设您真的不需要再进一步了。@hrishikeshp19:这简化了选择器,因此它只在有前面的元素时使用:n子元素,结果是一个更干净的选择器BODY>DIV>DIV>UL>LI:nth-child2>UL>LI:nth-child5.@hrishikeshp19:这增加了一个优化,如果元素有一个ID属性,它只返回一个ID选择器,因为ID在页面上必须是唯一的。
function f (domEl){
    var s = [],
        node = domEl;

    do {
        s.unshift(build_nth_selector(node));
    } while((node = node.parentNode) && node !== document.body)

    s.unshift('BODY')

    return s.join(' > ');
}

function build_nth_selector(node) {
    var p = 1,
        n_name = node.nodeName.toUpperCase();
    while (node = node.previousElementSibling)
        ++p;
    return n_name + ':nth-child(' + p + ')'
}

var $ = function(s) { return document.querySelector(s); };

var el = document.getElementById('target');

alert(f(el));

alert($(f(el)) === el);
BODY > DIV:nth-child(1) > DIV:nth-child(1) > UL:nth-child(1) > LI:nth-child(2) > UL:nth-child(1) > LI:nth-child(5)