I have this HTML:
<ul class="box">
<li>One</li>
<li>Two</li>
<li>Three</li>
...
</ul>
Now I want to add first li class current and second class next. Then after etc 1 second move the classes "down" so second will have class current and third will have class next. After 1 second again current class to third child and next to first. And so on.. forever. But how can I do it? Is there any common solution for doing this?
Try
jQuery(function () {
var $lis = $('.box li'),
$cur = $lis.first().addClass('current'),
$next = $cur.next().addClass('next');
setInterval(function () {
$cur.removeClass('current');
$cur = $next.removeClass('next').addClass('current');
$next = $cur.next();
if (!$next.length) {
$next = $lis.first();
}
$next.addClass('next');
}, 1000);
});
Demo: Fiddle
Here is js code for that.
var index = 0;
function InfinitiveSwitching() {
var items = $(".box li");
var previousIndex = index - 1;
if (0 > previousIndex) {
previousIndex = $(items).length - 1;
}
var previousImage = $(items).get(previousIndex);
$(previousImage).removeClass('current');
var currentImage = $(items).get(index);
$(currentImage).removeClass('second');
$(currentImage).addClass('current');
index++;
if (index >= $(items).length) {
index = 0;
}
var secondImage = $(items).get(index);
$(secondImage).addClass('second');
window.setTimeout(function () { InfinitiveSwitching() }, 1000)
}
Good luck
Related
How do i make it so that when i click a link itll lead to me a certain div on my slideshow. Thanks
<script>
function Divs() {
var divs= $('#parent div'),
now = divs.filter(':visible'),
next = now.next().length ? now.next() : divs.first(),
speed = 1000
now.fadeOut(speed);
next.fadeIn(speed);
}
var timesClicked = 0;
i = setInterval(Divs, 4000);
$(".slideshow-container").click(function() {
timesClicked += 1;
if (timesClicked%2==0) {
i = setInterval(Divs, 3000);
}
else {
clearInterval(i)
}
})
</script>
<div class ='box' id = 'food'>
I have an array with predefined lines:
var linesArr = ["asd", "dsa", "das"];
I have a div, which i created with JS and styled it with my CSS:
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
Right now i have that code that can animate the texts fadeIns and fadeOuts on click:
$(div).click(function(){
$(this).fadeOut(1000, function() {
$(this).text("Random text").fadeIn(2000);
});
});
But it is not a cycle that can iterate through my array items, it will be showing the predefined text all the time.
I tried to write a cycle that can work through that, but got lost:
$(div).click(function(){
for (var i = 1; i < linesArr.length; i++) {
$(div).fadeOut(1000, function() {
$(this).html(linesArr[i].fadeIn(2000));
});
};
});
That cycle is not working, i don't have any console errors, but the logic here is flawed. Can somebody help me?
Do you want like this
var linesArr = ["asd", "dsa", "das"];
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
document.body.appendChild(div);
$(div).click(function(){
//for (var i = 1; i < linesArr.length; i++) {
$(div).fadeOut(1000, function() {
index = linesArr.indexOf($(this).html()) + 1;
$(this).html(linesArr[index % linesArr.length]);
$("div").fadeIn(2000);
});
//};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use a pointer (show in this case) to keep track of the current element being shown. Then on each click fade out the current and fade in the next.
I'm also using a module % to loop back to the first element when you reach the end.
var linesArr = ["asd", "dsa", "das"];
var show = 1;
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
$(document.body).append(div);
$(div).click(function() {
$(div).fadeOut(1000, function() {
$(this).html(linesArr[show++ % linesArr.length]).fadeIn(2000);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If you need a cycle, you can use a loop in an IIFE:
$('div').click(function () {
(function loop(i) {
$('div').html(linesArr[i]).fadeOut(1000, function () {
$(this).html(linesArr[i]).fadeIn(2000);
i++;
if (i < linesArr.length) {
loop(i);
}
});
})(0);
});
var linesArr = ["asd", "dsa", "das"];
$('div').click(function () {
(function loop(i) {
$('div').html(linesArr[i]).fadeOut(1000, function () {
$(this).html(linesArr[i]).fadeIn(2000);
i++;
if (i < linesArr.length) {
loop(i);
}
});
})(0);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Click Me</div>
When the complete callback runs your i variable already reached the last value. In order to preserve the variable scope you can use IIFE
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');
}
}
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');
}
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>
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>
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/
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");
}
You should have some conception of state that tracks which of the lis 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.
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
Want to display 3 items from ul at a time. And when user clicks to the next arrow each element is traversed and when control reaches to last item i.e 3rd item , next three items should be shown in place of first three items.
The list should not be circular, means after last item in the list there must not be first item.
Have created fiddle but it traversing in circular fashion.
I am traversing list using this,
$("#rightArrow").click(function (e) {
var curr = $("#itemsListBox ul li:last");
curr.parent().prepend(curr);
});
$("#leftArrow").click(function (e) {
var curr = $("#itemsListBox ul li:first");
curr.parent().append(curr);
});
http://jsfiddle.net/N6XrL/
You could simply hide and show the appropriate element instead of appending/prepending:
http://jsfiddle.net/N6XrL/2/
var $elements = $("#itemsListBox ul li");
var count = $elements.length;
var showNum = 3;
var counter = 0;
$("#rightArrow").click(function (e) {
if (counter + showNum < count) {
counter++;
}
display();
});
$("#leftArrow").click(function (e) {
if (counter > 0) {
counter--;
}
display();
});
function display() {
$elements.hide();
$elements.slice(counter, counter + showNum).show();
}
display();
You should keep track of you current picture. like in following code.
var items_count = $("#itemsListBox ul li").length, current_item_counter=0;
$("#rightArrow").click(function(e) {
if(current_item_counter<items_count)
{
var curr = $("#itemsListBox ul li:last");
curr.parent().prepend(curr);
current_item_counter++;
}
});
$("#leftArrow").click(function(e) {
if(current_item_counter> 0)
{
var curr = $("#itemsListBox ul li:first");
curr.parent().append(curr);
current_item_counter--;
}
});
here is jsFiddle.
I have the following script:
(function($) {
$.fn.easyPaginate = function(options){
var defaults = {
step: 4,
delay: 100,
numeric: true,
nextprev: true,
controls: 'pagination',
current: 'current'
};
var options = $.extend(defaults, options);
var step = options.step;
var lower, upper;
var children = $(this).children();
var count = children.length;
var obj, next, prev;
var page = 1;
var timeout;
var clicked = false;
function show(){
clearTimeout(timeout);
lower = ((page-1) * step);
upper = lower+step;
$(children).each(function(i){
var child = $(this);
child.hide();
if(i>=lower && i<upper){ setTimeout(function(){ child.fadeIn('fast') }, ( i-( Math.floor(i/step) * step) )*options.delay ); }
if(options.nextprev){
if(upper >= count) { next.addClass('stop'); } else { next.removeClass('stop'); };
if(lower >= 1) { prev.removeClass('stop'); } else { prev.addClass('stop'); };
};
});
$('li','#'+ options.controls).removeClass(options.current);
$('li[data-index="'+page+'"]','#'+ options.controls).addClass(options.current);
if(options.auto){
if(options.clickstop && clicked){}else{ timeout = setTimeout(auto,options.pause); };
};
};
function auto(){
if(upper <= count){ page++; show(); }
else { page--; show(); }
};
this.each(function(){
obj = this;
if(count>step){
var pages = Math.floor(count/step);
if((count/step) > pages) pages++;
var ol = $('<ol id="'+ options.controls +'" class="pagin"></ol>').insertAfter(obj);
if(options.nextprev){
prev = $('<li class="prev">prev</li>')
.appendTo(ol)
.bind('click', function() {
//check to see if there are any more pages in the negative direction
if (page > 1) {
clicked = true;
page--;
show();
}
});
}
if(options.numeric){
for(var i=1;i<=pages;i++){
$('<li data-index="'+ i +'">'+ i +'</li>')
.appendTo(ol)
.click(function(){
clicked = true;
page = $(this).attr('data-index');
show();
});
};
};
if(options.nextprev){
next = $('<li class="next">next</li>')
.appendTo(ol)
.bind('click', function() {
//check to see if there are any pages in the positive direction
if (page < (count / 4)) {
clicked = true;
page++;
show();
}
});
}
show();
};
});
};
})(jQuery);
jQuery(function($){
$('ul.news').easyPaginate({step:4});
});
which is a carousel-like plugin that produces this html structure for the navigation:
<ol id="pagination" class="pagin"><li class="prev">prev</li><li data-index="1" class="">1</li><li data-index="2" class="">2</li><li data-index="3" class="current">3</li><li class="next stop">next</li></ol>
And all I want is to enclose this list in a div. Seems simple, but appendTo doesn't want to cooperate with me, or I'm doing something wrong (I'd appreciate if you would help me understand what that is..)
So I'm modifying as such:
var ol = $('<ol id="'+ options.controls +'" class="pagin"></ol>');
var tiv = $('<div id="lala"></div>');
ol.appendTo('#lala');
tiv.insertAfter(obj);
I know how to chain, but I'm in "debugging" mode trying to understand why I don't get the result I imagine I would get:
<div id="lala>
<ol id="pagination><li>...... </li></ol>
</div>
I tried putting some console.log's to see the status of my variables but couldn't find something useful.. I guess there's something with DOM insertion I don't get.
You're appending the <ol> element to #lala before adding the latter to the document. There's nothing wrong with this, but since you're using an id selector, and the target element is not part of the document yet, the selector will not match anything.
To fix this, you can write:
var ol = $('<ol id="'+ options.controls +'" class="pagin"></ol>');
var tiv = $('<div id="lala"></div>');
ol.appendTo(tiv);
tiv.insertAfter(obj);
Or:
var ol = $('<ol id="'+ options.controls +'" class="pagin"></ol>');
var tiv = $('<div id="lala"></div>');
tiv.insertAfter(obj);
ol.appendTo('#lala');