Reputation: 356
I have two divs: #slider-next and #slider-prev. Also i have 4 li elements. On each click #slider-next i need to add .active class to each li. First look:
<ul class="items-list">
<li class="active" id="l1">One</li>
<li id="l2">Two</li>
<li id="l3">Three</li>
<li id="l4">Four</li>
</ul>
After click #slider-next it should looks like:
<ul class="items-list">
<li id="l1">One</li>
<li class="active" id="l2">Two</li>
<li id="l3">Three</li>
<li id="l4">Four</li>
</ul>
It should repeating by clicking like it was at start Here is my code but it adds class only for a second li:
function arrowNext() {
if( $('#l1, #l2, #l3, #l4').hasClass('active') ) {
$('.items-list li').removeClass('active');
$('li:nth-child(1)').next().addClass('active');
}
}
Upvotes: 0
Views: 180
Reputation: 964
Two comments:
In general I would prefer to use $(document).ready()
or something similar to ensure there is always one class="active"
(since you're doing a slider seems sensible) as opposed to seeing if that condition exists.
$('li:nth-child(1)')
selects the first <li>
always, not the one that was previously active. What you probably want instead is
$('li.active') // Selects the li with class active
.removeClass('active') // returns the same li acted on
.next() // selects the next li
.addClass('active'); // adds the class active
This method of "chaining" is part of what makes jQuery
so convenient :)
If you want it to "wrap around" you could do something like
var $next = $('li.active') // Selects the li with class active
.removeClass('active') // returns the same li acted on
.next(); // selects the next li
if ($next.length === 0) {
$next = $('li:first');
}
$next.addClass('active'); // adds the class active
Upvotes: 0
Reputation: 2944
If You need circular Next and Previous, you can try this:
var nextCircularIndex = function(currentIndex, totalIndex) {
currentIndex = currentIndex + 1;
return currentIndex % totalIndex;
}
var previousCircularIndex: function (currentIndex, totalIndex) {
currentIndex = currentIndex - 1;
return currentIndex < 0 ? totalIndex - 1 : currentIndex;
}
Then change arrowNext
like
var currentSlider = 0;
var totalSlider = 4;
function arrowNext() {
currentSlider = nextCircularIndex(currentSlider, totalSlider);
$("ul.items-list li.active").removeClass('active');
$("ul.items-list li:nth-child(" + currentSlider + ")").next().addClass('active');
}
function arrowPrevious() {
currentSlider = previousCircularIndex(currentSlider, totalSlider);
$("ul.items-list li.active").removeClass('active');
$("ul.items-list li:nth-child(" + currentSlider + ")").next().addClass('active');
}
Upvotes: 2
Reputation: 1674
I think it's a good way you to follow
$(".next").on("click", function(){
if($(".active").next("div").html() === undefined) {
$(".active").removeClass("active");
$("div").first().addClass("active");
} else {
$(".active").removeClass("active").next("div").addClass("active");
}
})
$(".prev").on("click", function(){
if($(".active").prev("div").html() === undefined) {
$(".active").removeClass("active");
$("div").last().addClass("active");
} else {
$(".active").removeClass("active").prev("div").addClass("active");
}
})
here's a fiddle: https://jsfiddle.net/v58jzp9L/
here is a update with a loop :) https://jsfiddle.net/v58jzp9L/2/
Upvotes: 1
Reputation: 361
Maybe something like this:
var list_items = $(".items-list li");
var li_active = 1;
var li_total = list_items.length;
$("#prev").click(function() {
list_items.removeClass('active');
if (li_active == 1) {
li_active = li_total;
} else {
li_active--;
}
$('.items-list li:nth-child(' + li_active + ')').addClass('active');
});
$("#next").click(function() {
list_items.removeClass('active');
if (li_active == li_total) {
li_active = 1;
} else {
li_active++;
}
$('.items-list li:nth-child(' + li_active + ')').addClass('active');
});
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="items-list">
<li class="active" id="l1">One</li>
<li id="l2">Two</li>
<li id="l3">Three</li>
<li id="l4">Four</li>
</ul>
<button id="prev">Prev</button>
<button id="next">Next</button>
Upvotes: 1
Reputation: 12163
I would approach it like this
function arrowNav(prev) {
// get the current index of the active item
var index = $('.items-list li.active').index();
// remove the active class from all items
$('.items-list li').removeClass('active');
// add or subtract one if next or previous
var newIndex = prev ? index - 1 : index + 1;
// rolling over the top or bottom
if (newIndex < 0)
newIndex = $('.items-list li').length - 1;
else if (newIndex >= $('.items-list li').length)
newIndex = 0;
// setting the class of the new active item
$('.items-list li').eq(newIndex).addClass('active');
}
$('#slider-prev').on('click', function() {
arrowNav(true)
});
$('#slider-next').on('click', function() {
arrowNav(false)
});
.active {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="items-list">
<li class="active" id="l1">One</li>
<li id="l2">Two</li>
<li id="l3">Three</li>
<li id="l4">Four</li>
</ul>
<button id="slider-prev">
Prev
</button>
<button id="slider-next">
Next
</button>
Upvotes: 1
Reputation: 1546
You should have some conception of state that tracks which of the li
s are "active"
. This could be as simple as an array that looks like this:
const state = {
list_items: [false, true, false, false]
};
Or, more succinctly, a single number, representing the index of the li
that is "active"
const state = {
active_list_item: 1
};
Then when you press next, you can increment state.active_list_item
appropriately. Find a way to manage overflow. Does it wrap? If not, maybe use a createClamp(..)
function. Otherwise, use a createWrap(..)
function.
When the state is changed, you will want the appropriate DOM side effects to flow from the state change.
let list_items = document.getElementsByClassName('items-list')[0].children;
list_items = [].slice.apply(list_items);
list_items.forEach((list_item, i) => {
if (i === state.active_list_item) {
list_item.classList.add('active');
}
else {
list_item.classList.remove('active');
}
});
You should be able to figure out how to create the "previous" functionality now.
Upvotes: 0
Reputation: 301
You could use something like
var item = $("ul").closest("li");
var item2 = item.closest(".active");
item2.toggleClass("active");
if (item2.next("li") != null) {
item2.next("li").toggleClass("active");
} else {
item.toggleClass("active");
}
Upvotes: 0