jQuery: only direct descendant selector

2019-06-16 03:54发布

问题:

I have the following structure :

<ul>
    <li><a>link</a>
        <ul>
            <li>
                <a>link</a>
                <ul>
                    <li><a>link</a></li>
                    <li><a>link</a></li>
                    <li><a>link</a></li>
                </ul>
            </li>
             <li>
                <a>link</a>
                 <ul>
                    <li><a>link</a></li>
                    <li><a>link</a></li>
                    <li><a>link</a></li>
                 </ul>
             </li>
        </ul>
    </li>
    <li>
        <div>content 
            <ul>
                <li><a>link</a></li>
                <li><a>link</a></li>
                <li><a>link</a></li>
            </ul>
         </div>
    </li>
    <li><a>link</a></li>
    <li><a>link</a></li>
    <li><a>link</a></li>
</ul>

I wanna select only the anchors that fall directly under the <li> tags ( children) but not the ones that fall under other tags (grandchildren) if i do

$('ul li> a')

I will also get the the ul which is nested under the div. is there a "clean" way to do this? thank you

ps: I would like to have a generic selector ( this is for a menu pluggin so I want it to ignore all the anchor tags that don't fall directly in the flow of a menu)

回答1:

The Final Solution

This answer has been completely re-edited to keep it updated. The final solution is basically a selector, where starting from the original <ul> element's ID, select all anchors within the list items that doesn't break the menu structure's flow. That is, if there is an element other than <ul> or <li> nested within, don't select anything within those elements, even if there is a menu within.

The resulting selector (#root is the ID of the main <ul>) :

$('#root > li > a, #root ul:not(#root :not(ul,li) ul) > li > a')

You can try a demo over here: http://jsfiddle.net/9gPzQ/31/

However the original poster @salmane wanted to do it for a plugin, which already comes with an element passed in, so he came up with the following code to do the same as above, but within already selected objects passed as selector context:

$('li >a',this.content).not($(':not(ul,li) a',this.content))

Other interesting selectors

Along the way of finding a solution, certain interesting selectors came up due to my misunderstanding of the problem, but I'll include them here anyway just for the record, it might come in handy for some. :)

This selector selects the anchors of list items that are on the top level of a menu, wherever they are on the page:

$(':not(li) > ul > li > a')

This selector selects the anchors of list items that are on the top level of a menu, ignoring menus that are nested within other menus, even if they are nested within other containers:

$('ul:not(ul ul) > li > a')

You can try these to selector in a demo here: http://jsfiddle.net/9gPzQ/4/



回答2:

I think what you're looking for is:

$('ul:parent ul li>a')

This will give you all the li>a's without the div or anything in it.



回答3:

Thanks to the Great input of @DarthJDG

this is the solution

$('li >a',this.content).not($(':not(ul,li) a',this.content))

this.content being the object referenced by the plugging in this case the object is the parent UL

I hope this helps someone