Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery next() and elements that aren't necessarily next to each other

Tags:

jquery

I know there are other questions on the subject, but I haven't been able to get any of the to work, so I'll ask again:

I have an html list that looks like this:

<ul>
  <li>Item one</li>
  <li>Item two</li>
  <li>Item three</li>
  <li>Item four</li>
  <li>Item five</li>
</ul>

Using jQuery some of the li tags are hidden, and some are visible using .show() and .hide() e.g.

<ul>
  <li style="display: block">Item one</li>
  <li style="display: none">Item two</li>
  <li style="display: none">Item three</li>
  <li style="display: block">Item four</li>
  <li style="display: block">Item five</li>
</ul>

I've also go another bit of jQuery which adds a class to one of the li tags so the code looks like this (the code will only ever add this class to a visible li):

<ul>
  <li style="display: block" class="highlight">Item one</li>
  <li style="display: none">Item two</li>
  <li style="display: none">Item three</li>
  <li style="display: block">Item four</li>
  <li style="display: block">Item five</li>
</ul>

What I then need to do is when an event happens (in this case the user hits the down key) I want the li with the class to remove it's class and add the class to the next visible li. I would have thought that this would do it:

if (event.keyCode == '40') {
  $('li.highlight').removeClass('highlight').next(':visible').addClass('highlight');
}

But this only works if the next visible li is the next li anyway. How can I get it to choose the correct element in all cases?

like image 667
chrism Avatar asked Dec 29 '22 09:12

chrism


1 Answers

Try:

$('li.highlight')
    .removeClass('highlight')
    .nextAll(':visible:first')
    .addClass('highlight');

Annoyingly, and confusingly, next will only select the very next sibling. The fact that you can filter by passing in a selector makes you think that it will keep going until it finds something, but that is not the case. The filter expression will cause next to grab the very next element only if it matches the passed selector.

See http://api.jquery.com/nextAll/

like image 165
karim79 Avatar answered Dec 30 '22 22:12

karim79