Getting nth-child of a variable full of li tags

Refresh

April 2019

Views

567 time

1

I've got a variable, let's call it $listObjects. The data of it is as followed....

<li>Data Here 1</li>
<li>Data Here 2</li>
<li>Data Here 3</li>
<li>Data Here 4</li>

I have tried every way I can think of, and can't find out how to get the nth-child of the list tags. Is this possible? I basically want to use nth-child(3n) on the $listObjects variable.

If the method above isn't possible, the $listObjects variable is being populated like so...

var $listObjects = $data.find('li[data-type=' + $filterType + ']');

Would it be possible to add the nth-child(3n) to that line?

1 answers

1

Use filter:

Reduce the set of matched elements to those that match the selector or pass the function's test.

So this should do it:

$listObjects.filter(':nth-child(3n)')

If you don't need $listObjects for anything else then you could include the :nth-child in your original find:

$data.find('li[data-type=' + $filterType + ']:nth-child(3n)');

Let us clarify what's going on a little bit. Given this HTML:

<ul>
    <li data-id="a">One</li>
    <li>Two</li>
    <li data-id="a">Three</li>
    <li data-id="a">Four</li>
    <li data-id="a">Five</li>
    <li data-id="a">Six</li>
    <li data-id="a">Seven</li>
</ul>

If we say $('li[data-id]') we'll get One, Three, Four, Five, Six, and Seven for the obvious reason.

If we say $('li[data-id]').filter(':nth-child(3n)'), we'll get Three and Six when you're probably expecting to get Four and Seven. What happens here? The :nth-child selector is being applied to all of the children of the <ul> rather than just those that match [data-id]. From the fine manual:

The supplied selector is tested against each element; all elements matching the selector will be included in the result.

So this behavior matches the spec even if it is a little confusing and the spec could be more explicit on how things interact.

If we say $('li[data-id]:nth-child(3n)') then we get the (expected?) Four and Seven, i.e. every third element of $('li[data-id]').

And finally, we can say this:

$.grep($('li[data-id]'), function(e, i) { return (i + 1) % 3 == 0 }));

​ Remember that nth-child is a CSS selector and thus 1-based, hence the (i + 1) in the test function. That will give us every third element again so we get Four and Seven. Note that $.grep gives you a plain array of DOM elements so you'll want to wrap that array in $() if you jQuery-ified version.

Demo: http://jsfiddle.net/fw4xr/


Summary: filter may not be what you want but adding the :nth-child(3n) to the original selector probably is. Alternatively, you could use $.grep to grab the part of the $listObjects array that you're interested in. And the behavior of filter is a bit confusing.