38

Let's say I have following HTML:

<span>
    <span id="x1" class="x">X1</span>
</span>
<span>
    <span>
        <span id="x2" class="x">X2</span>
    </span>
</span>

And $(this) is the <span id="x1" ...>.

What is the best way to find next element matching .x with jQuery?
The structure of the actual document is unpredictable, so the HTML provided is only an example.

I can't use nextAll as it only finds siblings.
If I do $('.x'), it finds all, but I'll have to iterate/compare.
Is there a better solution?

See also: http://jsfiddle.net/JZ9VW/1/.

Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162

2 Answers2

46

Select all elements with class x, calculate the index of the current element and get the element with the index + 1:

var $x = $('.x');
var $next = $x.eq($x.index(this) + 1);

This works because elements are selected in document order. You only have to select all .x elements once on page load (if they are not dynamically created).

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    Thanks, I did not know about `index()`. I'll accept when SO allows me (time limitation). – Andrey Shchekin Dec 26 '12 at 01:40
  • I mean, `.index` is probably just iterating over the elements as well, but at least you don't have to do so explicitly. AFAIK this is the only way if you don't know any other relation between the nodes. – Felix Kling Dec 26 '12 at 01:54
  • This is far better than traversing the whole tree and playing with prevAll() etc! Thanks! – Matt Komarnicki Jul 27 '15 at 10:18
1

You could use xpath:

document.evaluate('following::*[@class="x"], elt, null, XPathResult.ANY_TYPE, null);

or you could use a walker:

var walker = document.createTreeWalker(elt, NodeFilter.SHOW_ELEMENT, function(node) {
    return node.classList.has('x');
});

while (walker.nextNode) {
    do_something_with(walker.currentNode);
}
  • I see your point, but unless it is critical path (and it is not for me), added complexity will outweigh performance gain. Also, are you sure about several orders of magnitude? It should be using `querySelector` internally anyway. – Andrey Shchekin Dec 26 '12 at 08:51
  • I agree that directly processing the DOM is generally faster, but if you make such a claim, you should back it up with a http://jsperf.com/ test. – Felix Kling Dec 26 '12 at 13:28