Reputation: 7315
I am trying to carry a class between li
's with combine each()
and eq()
methods when buttons clicked. I am using same code with previous and next buttons except i+1
and i-1
but it is returning me different problems.
html:
<span class="prev">prev</span>
<ul>
<li>0</li>
<li>1</li>
<li class="active">2</li>
<li>3</li>
<li>4</li>
</ul>
<span class="next">next</span>
jQuery:
var li = $('li');
$('.prev').click(function() {
li.each(function(i) {
if ( $(this).hasClass('active') ) {
console.log(i);
//this returning current true value = 2
li.removeClass('active');
li.eq(i-1).addClass('active');
//this is working better
//problem is: not selecting 4
}
});
});
$('.next').click(function() {
li.each(function(i) {
if ( $(this).hasClass('active') ) {
console.log(i);
//this returning current true value = 2
//problem starts:
//li.removeClass('active');
//when this is active; all active classes are gone
li.eq(i+1).addClass('active');
//try to select next 'li' here
//but it is selecting all li's bigger than current value
}
});
});
Upvotes: 1
Views: 10247
Reputation: 3214
You should return false;
after you find your first class of active
:
http://jsfiddle.net/ufomammut66/np4Pt/
Whats happening is your iterating over the elements moving forward and changing each one in order. So as you go through each case your setting the next one in sequence as active which in turn makes the next $(this).hasClass('active')
check true. This is why the prev event is working, we're moving in reverse order of the loop. So we just need to stop iterating over our collection after we find our active case.
Edit 1
You can use .length
on any selected object to get how many are returned. So in the example code you provided we can use li.length
to get how many li elements are on the page. You may want to use a class selector just to ensure that other li elements are not being used to calculate your ceiling. I have updated the jsFiddle to reflect these changes.
Upvotes: 1
Reputation: 1589
I'd try using something more like:
$(".next").click(function(){
if($("li.active").next().length > 0){
$("li.active").removeClass("active").next("li").addClass("active");
}
});
$(".prev").click(function(){
if($("li.active").prev().length > 0){
$("li.active").removeClass("active").prev("li").addClass("active");
}
});
using the 'next' selector: Jquery Next
I avoid math when possible. Counting is hard :-). That said I'm thinking your problem above may be with the index. Hard to say. I'd avoid using selectors like "li" when dealing with a list like this. Try putting a class on the 'ul' portion of it and addressing your li's as: ".myList li"
Upvotes: 4
Reputation: 6020
Try the following updated jsFiddle:
var li = $("li");
$(".prev").click(function() {
var activeLI = $("li.active");
var index = $(activeLI).index();
$(activeLI).removeClass('active');
if (index > 0) {
$(activeLI).prev().addClass('active');
} else {
$(li).last().addClass('active');
}
});
$(".next").click(function() {
var activeLI = $("li.active");
var index = $(activeLI).index() + 1;
$(activeLI).removeClass('active');
if (index < li.length) {
$(activeLI).next().addClass('active');
} else {
$(li).first().addClass('active');
}
});
This will loop around to last element active (if previous on first) and first element active (if next on last).
Upvotes: 0
Reputation: 318182
If for some reason you need the index, you could always do:
$('.prev').on('click', function() {
var i = $(".active").index();
i--;
$(".active").removeClass('active');
$('li').eq(i).addClass('active');
});
$('.next').on('click', function() {
var i = $(".active").index();
i = i >= $('li').length-1 ? 0 : i+1;
$(".active").removeClass('active');
$('li').eq(i).addClass('active');
});
If not :
$('.prev, .next').on('click', function() {
if ($(".active")[$(this).attr('class')]().index()!=-1)
$(".active").removeClass('active')[$(this).attr('class')]().addClass('active');
});
Upvotes: 1
Reputation: 4474
You could try even this:
$('.prev').click(function() {
var el = $.find('li[class=active]');
//check if are prev li
if(!$(el).prev().is(':first')) $(el).removeClass('active').prev().addClass('active');
});
$('.next').click(function() {
var el = $.find('li[class=active]');
//check if are next li
if(!$(el).next().is(':last')) $(el).removeClass('active').next().addClass('active');
});
Upvotes: 0