6

I was wondering how jQuery traverses the DOM when you use a selector. Does it look up each "first level" element, and then look inside each one of them? Or does it look at every children of those "first level" elements one by one?

Let me explain what i imagined with some quick examples, given the following selector :

$("div p#target")

Does it proceed more like :

[1] <div>
    [3] <div>
        [5] <p id="target"></p>
        </div>
    </div>
[2] <div>
    [4] <div>
            <p></p>
        </div>
    </div>

Or like :

[1] <div>
    [2] <div>
        [3] <p id="target"></p>
        </div>
    </div>
    <div>
        <div>
            <p></p>
        </div>
    </div>
aaaaaa
  • 2,588
  • 3
  • 26
  • 31
  • jQuery uses SizzleJS, it is not an answer to your question but maybe their docs can help you: http://sizzlejs.com/ and https://github.com/jquery/sizzle/wiki/Sizzle-Home – Thizzer Oct 31 '11 at 19:34
  • JQuery doesn't always use sizzle. For example, `$('#mydiv')` will not use sizzle. In chrome and firefox, `$('.mydiv')` won't use sizzle but in IE<9 it will. – AlienWebguy Oct 31 '11 at 19:43
  • alright, no predictable way to know how it will work then :/ – aaaaaa Oct 31 '11 at 19:44
  • Please see http://stackoverflow.com/questions/3177763/what-is-the-fastest-method-for-selecting-descendant-elements-in-jquery/3177782#3177782. – weir Oct 31 '11 at 19:49
  • @user704808 interesting, but not my question though – aaaaaa Oct 31 '11 at 19:55

3 Answers3

1

Traversal happens in the same order the elements are in the DOM:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
    <head>
        <title>query traversal order</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    </head>
    <body>
        <ul>
            <li id="parent1">
                <ul>
                    <li id="child1"></li>
                    <li id="child2"></li>
                </ul>
            </li>
            <li id="parent2">
                <ul>
                    <li id="child3"></li>
                    <li id="child4"></li>
                </ul>
            </li>
        </ul>
        <script type="text/javascript">
            // keep a list of ids
            var arr = [];
            // loop over all li elements
            $('li').each(function(){
                // add their id to the array
                arr.push($(this).attr('id'));
            });
            // show contents of the array
            alert(arr.join(', '));
        </script>
    </body>
</html>

This will alert "parent1, child1, child2, parent2, child3, child4";

Kris
  • 40,604
  • 9
  • 72
  • 101
  • In every known browser? Looking at what some people said above this doesnt seem very consistent. i could eventually try on my own, but who knows, maybe you already did :D – aaaaaa Oct 31 '11 at 19:50
  • Well no, I just ran this in Safari straight from TextMate, but it makes a lot of sense since it has to find all nodes in the document. Any other order would be more difficult to implement a tree traversal for. – Kris Oct 31 '11 at 19:53
  • That's true, even though "making sence" isnt a sufficient proof for anything. I'll run your snippet in some browsers and come back here if we were wrong. – aaaaaa Nov 01 '11 at 12:54
0

If you mean the order by which it goes through them, I'm assuming that's not jQuery itself but the actual DOM functions. This is probably implementation dependant and I would not rely on that (unless maybe it's defined in the specs).

What were you trying to accomplish to need to know such detail? Maybe we can help resolve the actual problem.

Alex Turpin
  • 46,743
  • 23
  • 113
  • 145
  • Traversal is very likely specified to happen in document order, ie. depth-first (diagram 2 in the OP). – AKX Oct 31 '11 at 19:43
  • 1
    I'm not facing any particular problem, but am making an extensive use of jQuery, and knowing how it works inside would help me make better selectors for example. If it works like in my first example, i would rather give an id to the first div so that it doesnt bother looking at the second one – aaaaaa Oct 31 '11 at 19:43
0

In your example, I'd hope it would process like this:

<div> 
[2] <div>                   //check it matches the selector
    [1] <p id="target"></p> //document.getElementById is cheap
    </div>
</div>
<div>
    <div>
        <p></p>
    </div>
</div>
Eric
  • 95,302
  • 53
  • 242
  • 374
  • haha yes that's true, but this example was for the show, i'm interested in what happens with more complex DOMs – aaaaaa Oct 31 '11 at 19:51