1

I want to write a function

function f (domEl){
    //some code here

    //returns a string
}

such that:

$(f(domEl))[0] == domEl

should always return true (of course, regardless at what hierarchy domEl is):

As an example, Let's say:

HTML
    body
        ul
            li
            **li**
            li
                ul
                    li

and, I want to select bold li element. I get that element and pass that into my function f.

12
  • This doesn't make too much sense to me. Is domEl of type HtmlElement i.e. that would be returned from document.getElementById()? Commented Mar 1, 2012 at 4:53
  • neither did it make sense to me, but It was asked as an interview question. But, having css selector string from a DOM element might be useful. Commented Mar 1, 2012 at 4:56
  • <ul><li><**li**> is wrong HTML tag. <li> always comes under <ul>. So, How three <li> comes consecutively here ? Commented Mar 1, 2012 at 5:09
  • This is nothing to do with hierarchy, $("<any_selector>") returns a special jquery object and standard javascript returns "standard" htmlXXElement types. If you pass a DOMElement into $() it converts it into a JQuery object. Asking for $(domEl) == f(domEl) makes more sense, unless they want you to change the JQuery source. Commented Mar 1, 2012 at 5:10
  • @gideon: And $ means jQuery in this code? Commented Mar 1, 2012 at 5:14

1 Answer 1

4

DEMO: http://jsfiddle.net/vzWgb/

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);

The selector looks like this (for the code I used in the example)...

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)
Sign up to request clarification or add additional context in comments.

9 Comments

It's really a smart java script
I am sorry, but its not working for all cases, have a look here: jsfiddle.net/vzWgb/2
@hrishikeshp19: Here's an update that builds the nth-child selector for each element on the way up. It stops at the body assuming that you really don't need to go any further.
@hrishikeshp19: And here's another one that simplifies the selector so it will only use :nth-child() when there are previous elements, resulting in a cleaner selector BODY > DIV > DIV > UL > LI:nth-child(2) > UL > LI:nth-child(5).
@hrishikeshp19: And one more that adds an optimization where if the element has an ID attribute, it simply returns an ID selector, since IDs must be unique on the page.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.