Reputation: 3730
Backstory: I have HTML that's been searched for a phrase, which puts a span around each instance. So if I search for Lorem, every place that word appears, it will look like this:
<span class="live-search-highlight">Lorem</span>
Which gives it a little highlight.The very first instace is given a different class with a more distinct highlight like this:
<span class="highlight-current">Lorem</span>
Question: I want to click a button, and starting at .highlight-current
, I want to find the next instance of .live-search-highlight
and switch its class to .highlight-current
. How can I achieve this with jQuery? Here is what I have so far, which only works once:
$(document.body).on('click','.button', function(){
// Find highlight-current, then get the next instance and make that one current
$('.highlight-current').parent().nextAll(".live-search-highlight").eq(0).removeClass('live-search-highlight').addClass('highlight-current');
// Reset the previous one so it's no longer current
$('.highlight-current:first').removeClass('highlight-current').addClass('live-search-highlight');
});
JsFiddle: http://jsfiddle.net/kthornbloom/g5skaek7/3/
Upvotes: 2
Views: 88
Reputation: 171690
Simpler to just create a collection of all of the highlighted elements. Then use indexing to determine position of current/next.
Following will revert back to the start when the last one is reached
// create collection of all highlighted elements
var $highlights = $('.live-search-highlight'),
// isolate the current one from collection and remove the secondary class
$currHighlight = $highlights.filter('.highlight-current').removeClass('highlight-current'),
// use index of current to determine next
nextIndex = $highlights.index($currHighlight) + 1;
// revert to beginning if index is at the end
if(nextIndex === $highlights.length){
nextIndex = 0;
}
// add secondary class to next (or first) in collection
$highlights.eq(nextIndex).addClass('highlight-current');
I would leave the main class and only add/remove the secondary class
Upvotes: 3
Reputation: 832
The issue is that your code looks for the next .live-search-highlight
via it's parent's siblings. This works the first time because the 1st highlight's parent is at the same level as the 2nd highlight. It doesn't work thereafter because it looks for highlights in the body's siblings.
body
h1
highlight1 -> parent = h1 (has highlight siblings)
highlight2 -> parent = body (doesn't have any siblings)
highlight3
You would have to store either:
Upvotes: 1
Reputation: 1404
This should work.
var item_count = 0
$('.button').click(function(){
$('.live-search-highlight').eq(item_count - 1).removeClass('highlight-current');
$('.live-search-highlight').eq(item_count).addClass('highlight-current');
item_count++
});
Upvotes: 0
Reputation: 792
It helps if you don't remove 'live-search-highlight' class and instead increment an index you store. This allows you to loop back around in the document and would make implementing forward/back controls easy.
var currentIndex = 0,
totalMatches = 0,
currentClass = 'highlight-current',
normalClass = 'live-search-highlight';
$(document.body).on('click','.button', function(){
var matches = $('.'+normalClass);
totalMatches = matches.length;
if(totalMatches === 0){
return;
}
var newIndex = (currentIndex === totalMatches - 1) ? 0 : currentIndex + 1;
matches.eq(currentIndex).removeClass(currentClass);
matches.eq(newIndex).addClass(currentClass);
currentIndex = newIndex;
});
Check the fiddle: http://jsfiddle.net/e00x5pbd/1/
Upvotes: 1