Udders
Udders

Reputation: 6976

jquery select all children after nth-child

I am working with jquery and creating show hide lists, I need hide all the child list items that follow the 6th child in the ul. Normally I would do this by setting the height and then changing the height on click of a click, but for this to work I need to add overflow:hidden to my css, and this is not an option.

How would I get all the child list elements that are greater than the 7th child?

Something like,

$("ul li:6n").domeSomething()

Upvotes: 7

Views: 9876

Answers (4)

gdoron
gdoron

Reputation: 150253

How would I get all the child list elements that are greater than the 7th child?

Select the element index = 7+

$("ul li:gt(6)").domeSomething()

:gt selector

The selector uses the zero base index:

Note that since JavaScript arrays use 0-based indexing, these selectors reflect that fact. This is why $('.myclass:gt(1)') selects elements after the second element in the document with the class myclass, rather than after the first. In contrast, :nth-child(n) uses 1-based indexing to conform to the CSS specification.

Upvotes: 18

Oleg
Oleg

Reputation: 221997

I wanted to write my answer only to discuss two previous answers: the answer from gdoron and the answer from neu-rah. If we would see on voting count one can see that the most reader find doron's answer better. I disagree and I try to explanation why.

The explanation you would find the documentation of :gt() Selector (see "Additional Notes:" here):

Because :gt() is a jQuery extension and not part of the CSS specification, queries using :gt() cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use $("your-pure-css-selector").slice(index) instead.

You can test the code with here or better here (with non-minimized code of jQuery 1.7.2). The code use just the statement $("ul li:gt(6)").css("color", "red");. You will better understand the problem if you start the demo in Developer Tools of Chrome with activated button "Pause on exceptions". You will see the following exception (it will be not the first one):

enter image description here

So you can see that the current implementation of jQuery try to use native querySelectorAll() of the web browser to get the best performance. After that the function $.makeArray will be used to make jQuery wrapper from the NodeList. In case of exception the line

return oldSizzle(query, context, extra, seed);

So you will have the best performance if you would use selectors supported by querySelectorAll(). For example

$("ul li").slice(7)

is better as

$("ul li:gt(6)")

I would you recommend to use more exact selectors whenever it's possible. For example if the parent <ul> element has id="menu1" then you can use

$("#menu1 >li").slice(7)

for the best results. It will help additionally in case of multiple <ul> elements on your page.

Someone can mention: the selector "ul li:gt(6)" works quickly enough. It's correct, but you should don't forget, that you use sometime selectors inside of loop or use it inside of functions which will be called inside of loops. So the difference between 10ms and 30ms can be much more clear if the execution time will be multiplicate to 100.

Moreover it somebody ask yourself the question how to implement some selection and get the answer, he/she will use the code pattern permanently. I think that it would be better to use the pattern which has performance advantage. Isn't so.

UPDATED: To clear the difference in performance of $("ul li:gt(6)"), $("ul li").slice(7) and $("#menu1 >li").slice(7) selectors I made additionally the demo. Everybody can test the difference in the web browser which he uses. You should additionally not forget, that in case of page having many other elements the id selector will work better.

On my computer the execution time of $("ul li").slice(7) and $("#menu1 >li").slice(7) are about the same (the page have very little elements) and is about 2.5-4.5 time better as the for $("ul li:gt(6)"). The results can depend on the number of li items, the number of elements on the page and many other things, but I hope that the test do clear shown that the usage of slice has performance advantage compared with the usage of :gt (exactly like we can read in the jqGrid documentation referenced before).

Upvotes: 3

neu-rah
neu-rah

Reputation: 1693

use slice to reduce a set

.slice(start[,end])

http://api.jquery.com/slice/

example (edited)

$("ul li").slice(6).doSomething(...)

Upvotes: 2

Engineer
Engineer

Reputation: 48793

Try this:

$('ul li:eq(6)').nextAll().domeSomething()

Upvotes: 1

Related Questions