Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference in results returned between .has() and :has()

Tags:

jquery

I have a gnarly navigation structure that can be generalized as:

<ul id="navigation">
    <li>
        A
        <ul>
            <li>
                B
                <ul>
                    <li>C</li>
                </ul>
            </li>
            <li>
                D
                <ul>
                    <li>
                        E
                        <ul>
                            <li>F</li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Sub-items are hidden until hover. I want to indicate that B, D, and E have sub-items by styling them so I used the selector:

$('#navigation > li li:has(ul)')

Which only returned B and D. Changing it to:

$('#navigation > li li').has('ul')

returned all of the correct items but I'm confused as to why.

EDIT

:has() doesn't appear to be affected (entirely) by nesting as

$('#navigation ul > li:has(ul)')

returns the same results as .has() above.

like image 942
Matthew Jacobs Avatar asked Oct 19 '10 17:10

Matthew Jacobs


1 Answers

From the jQuery API documentation:

:has selects elements which contain at least one element that matches the specified selector.

.has() reduces the set of matched elements to those that have a descendant that matches the selector or DOM element.

There is a related question here: jQuery: subtle difference between .has() and :has() , that seems to point to what the difference in the two could be.

However, It appears that :has doesn't look within a match in a nested fashion while .has() does because it returns a subset of matches as a jQuery object is able to match all descendants, even the nested one, like a regular jQuery selector.

like image 51
Moin Zaman Avatar answered Sep 23 '22 19:09

Moin Zaman