jQuery - interval not executed for the last slide - animation malfunction - javascript

I'm creating a slider but using a bunch of divs instead of images. I have 3 divs in total, the first two can move pretty well, but the last one just flies away really fast - it shows for a moment and then moves back to the first div. I just want it to show the same amount of time as the first two. Here's my html code:
<div id="ibToShow">
<div id='sliderWrapper'>
<div class="infoBox" id="infob1">
blablabla
</div>
<div class="infoBox" id="infob2">
blablabla
</div>
<div class="infoBox" id="infob3">
blablabla
</div>
</div>
</div>
And here's my jQuery code:
$(function () {
var width = '55vw';
var showTime = 2000;
var animationSpeed = 500;
var currentDiv = 1;
var $slider = $('#ibToShow');
var $sliderWrapper = $slider.find('#sliderWrapper');
var $infoBox = $sliderWrapper.find('.infoBox');
var interval;
function startSlider() {
interval = setInterval(function () {
$sliderWrapper.animate({'margin-left': '-=' + width}, animationSpeed, function(){
currentDiv++;
if (currentDiv === $infoBox.length){
currentDiv = 1;
$sliderWrapper.css('margin-left', 0);
}
})
}, showTime);
}
function stopSlider() {
clearInterval(interval);
}
$sliderWrapper.on('mouseenter', stopSlider).on('mouseleave', startSlider);
startSlider();
});
I sensed it might be because the animation stopped immediately after the third div showed up. But shouldn't it be waiting for what's set up in showTime?
This problem is still not fixed. Any takers?

You are changing margin left to 0 right after the previous animation ends.
I think this would work better :
function startSlider() {
interval = setInterval(function () {
if(currentDiv++ <== $infoBox.length) {
$sliderWrapper.animate({'margin-left': '-=' + width}, animationSpeed);
}
else {
$sliderWrapper.animate({'margin-left': '0'}, animationSpeed);
currentDiv = 0;
}
}, showTime);
}

Related

2 Javascript Timeouts occur simultaneously

I have 2 Javascript Timeouts which should make an animation, but the happen simultaneously, even if they have as timeout 1s.
JavaScript:
$( document ).ready(function() {
let filter = document.querySelector('.filter');
let body = document.querySelector('body');
setTimeout(moveRight, 1000);
setTimeout(scaleRotate, 1000);
function moveRight() {
filter.style.marginLeft="10%";
body.style.overflow = "hidden";
}
function scaleRotate() {
let deg = 90;
filter.style.webkitTransform = 'rotate('+deg+'deg)';
filter.style.width = "100vh";
}
});
HTML
<div class="header">
<div class="filter"></div>
<div class="header-text ml-5">
<h2 class="font-weight-bold">Andrei Bunea</h2>
<h3 class="mt-3">full stack developer</h3>
</div>
</div>
You set them similar delay. If you want scaleRotate to work 1 second after moveRight, you can set scaleRotate timer in moveRight timer:
setTimeout(moveRight, 1000);
function moveRight() {
console.log("moveRight");
setTimeout(scaleRotate, 1000);
}
function scaleRotate() {
console.log("scaleRotate");
}

Javascript: slideshow not slide when click

I have simple code where is slideshow which automatic slides every 5000ms.
Now I tried to make button which when I click on this button next image will not slide every 5000ms but when I click.
When I make code like this browser giving me errors.
Is there any solutions or I need make ned slideshow?
This is original code:
function cycleBackgrounds() {
var index = 0;
$imageEls = $('.container .slide');
setInterval(function () {
index = index + 1 < $imageEls.length ? index + 1 : 0;
$imageEls.eq(index).addClass('show');
$imageEls.eq(index - 1).removeClass('show');
}, 5000);
};
$(function () {
cycleBackgrounds();
});
This is added code:
function rightSlide() {
index = index + 1 < $imageEls.length ? index + 1 : 0;
$imageEls.eq(index).addClass('show');
$imageEls.eq(index - 1).removeClass('show');
}
EDIT added HTML
<section class="slide show" style="background-image: url('https://s7img.ftdi.com/is/image/ProvideCommerce/FTD_19_EDAY_19M3_HP_HEROBANNER?$ftd-product-banner-lv$');">
<div class="slide-content-wrapper">
<div class="slide-content">
<h2>02</h2>
</div>
</div>
</section>
<section class="slide" style="background-image: url('https://s7img.ftdi.com/is/image/ProvideCommerce/FTD_19_EDAY_19M3_HP_HEROBANNER?$ftd-product-banner-lv$');">
<div class="slide-content-wrapper right">
<div class="slide-content">
<h2>01</h2>
</div>
</div>
</section>
The problem is that you are creating an interval and then never clearing it. This means that once the interval is created it will keep going on forever (currently). You can read more about intervals here.
To briefly explain how to solve it:
You need to assign the interval to a variable
When you want to manually change images then clear the interval
Code snippet from the site:
var myVar = setInterval(myTimer, 1000);
function myTimer() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
function myStopFunction() {
clearInterval(myVar);
}
Inside of your code, when creating the interval you need to assign it into a variable and inside of the function rightSlide() you would need to clear it clearInterval(<yourIntervalHere>);
var intervalVariable = setInterval(function () {
index = index + 1 < $imageEls.length ? index + 1 : 0;
$imageEls.eq(index).addClass('show');
$imageEls.eq(index - 1).removeClass('show');
}, 5000);
function rightSlide() {
clearInterval(intervalVariable);
index = index + 1 < $imageEls.length ? index + 1 : 0;
$imageEls.eq(index).addClass('show');
$imageEls.eq(index - 1).removeClass('show');
}
You need to clear the interval but that's not the only problem:
Probably, the $imageEls and index variables are not in the scope of your custom click handler. It is definitely not the cleanest solution, but for now we will add them to the global window object
This is how I would write it (untested):
function cycleBackgrounds() {
window.index = (window.index + 1 < window.$imageEls.length) ? window.index + 1 : 0;
window.$imageEls.eq(index).addClass('show');
window.$imageEls.eq(index - 1).removeClass('show');
}
$(function () {
// add the new variables to window so they are globally accessible
window.index = 0;
window.$imageEls = $('.container .slide');
// start sliding images
window.slideshow_interval = setInterval(cycleBackgrounds, 5000);
// register onClick handler for the button with id "myButton"
$('#myButton').on('click', function(){
if (window.slideshow_interval != -1){
clearInterval(window.slideshow_interval);
window.slideshow_interval = -1;
}
cycleBackgrounds();
});
});

Stop timeout when user click and hold the picture

I have a gallery, that will show pictures to user for 5 to 5 seconds.
function slideSwitch() {
var current = $('#slideshow .active');
current.removeClass('active');
if (current.next().length) {
current.next().addClass('active');
myInterval = setTimeout(slideSwitch, 5000);
bar();
}
}
http://jsfiddle.net/6hcste51/
I'd like to pause the timeout when user click and hold the click on div holder.
For example, the timeout is in 3 seconds, if user click and hold the holder div I'd like to stop in 3 seconds until the hold ends, and then go to 4 and 5 seconds to call the function again.
I saw this function but I don't know how to add it in my slideSwitch(). any ideas?
selector.addEventListener('mousedown', function(event) {
// simulating hold event
setTimeout(function() {
// You are now in a `hold` state, you can do whatever you like!
}, 500);
}
you need to set timer function it can support pause and resume
need to set anmatin can support pause and resume and reset (i use jquery queue &
animations)
At last the code will be :
jsfiddle Link
//--------------------------global variables----------------
var isfirst= true;
var cycle_remaining = null;
var anim_time = 5000;//in mil sec
var downtime = null;
var myTimer = null;
var is_down = false;//is down event
var is_SpeedClick_getnext = false;//set to true you want to set click to get next image
//---------------------------timer-------------------------
function Timer(callback, delay) {
var timerId, start, remaining = delay;
cycle_remaining = remaining;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= new Date() - start;
cycle_remaining = remaining;
};
this.resume = function() {
start = new Date();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
cycle_remaining = remaining;
};
this.resume();
}
function slideSwitch() {
var current = $('#slideshow .active');
if (current.next().length) {
current.removeClass('active');
current.next().addClass('active');
myTimer = new Timer(slideSwitch, 5000);
resetanim();
startanim();
}
}
//--------------------- mouse control functions----------------------
$(document).on( "click", ".holder", function() {
if(isfirst){
isfirst = false;
slideSwitch();
}
});
$('.holder').on('mouseout mouseup', function(e) {
if(is_down && !isfirst){
is_down = false;
//set this if if you want to set click to get next image
if(downtime > new Date() - 100 && is_SpeedClick_getnext){
slideSwitch();
}else{
myTimer.resume();
startanim();
}
}
});
$(".holder").mousedown(function() {
if(!isfirst){
downtime = new Date();
is_down = true;
myTimer.pause();
puseanim();
}
});
//--------------------- animation control functions----------------------
//start or resume animation
function startanim() {
var myDiv = $( ".bottom_status" );
myDiv.show( "slow" );
myDiv.animate({
width:"100%"
},cycle_remaining );
myDiv.queue(function() {
var that = $( this );
//that.addClass( "newcolor" );
that.dequeue();
});
}
function rutanim() {
var myDiv = $( ".bottom_status" );
myDiv.show( "slow" );
myDiv.animate({
width:"100%"
}, anim_time );
myDiv.queue(function() {
var that = $( this );
//that.addClass( "newcolor" );
that.dequeue();
});
}
//to puse animation
function puseanim() {
var myDiv = $( ".bottom_status" );
myDiv.clearQueue();
myDiv.stop();
}
// to reset animation
function resetanim() {
var myDiv = $( ".bottom_status" );
myDiv.animate({
width:"1%"
}, 200 );
myDiv.queue(function() {
var that = $( this );
that.dequeue();
});
}
.holder{
display:none;
}
.active{
display:block;
}
.bottom_status{
position:absolute;
bottom:0;
background:blue;
width:0%;
height:10px;
left: 0;
margin-left: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id=slideshow>
<div class='holder active'>
Click here to start counting and click and hold to stop.
</div>
<div class='holder'>
text 2
</div>
<div class='holder'>
text 3
</div>
<div class='holder'>
text 4
</div>
</div>
<div class=bottom_status></div>
There is a Var called is_SpeedClick_getnext set to true you want to set click to get next
Note : the explanation in code comment
As mentioned you cant pause a setTimeout, but I have a solution which I think you might find useful.
I've created a second timer function that effectively stores the remaining time before a slide in the #slideshow element as an attribute every 500ms. If the user clicks on an image then it will cancel the original setTimeout and pauses the changing of the #slideshow attribute until the mouseup event. After the mouseup event is fired a new setTimeout is started using the remaining time stored in the attribute.
I also added a line of code to restart from the first image at the end of the slideshow (not sure if that's what you planned).
Hope this helps
// Start slider
slideSwitch();
// Start independent timer
timer();
function slideSwitch() {
// Select active slide and remove active status
var current = $('#slideshow .active');
current.removeClass('active');
// Check if there is a 'next' element and give active class, or return to first
if (current.next().length) {
current.next().addClass('active');
} else {
$("#slideshow img").first().addClass("active");
}
// Reset timer for the slide, store time and reset timer stop
myInterval = setTimeout(slideSwitch, 3000);
$("#slideshow").attr("time", "3000");
$("#slideshow").attr("timeStop", "false");
}
function timer() {
// Check if the slide countdown has been stopped
if ($("#slideshow").attr("timeStop") != "true") {
// Get last saved time and reduce by 500ms
tempTime = parseInt($("#slideshow").attr("time") - 500);
// Save time to slideshow attribute
$("#slideshow").attr("time", tempTime)
// Show countdown on label
$("#timerLabel").text(tempTime);
}
// Continue timer
myTimer = setTimeout(timer, 500);
}
// Add event for mousedown which cancels timer
$("#slideshow img").mousedown(function() {
// Stop timer and clear countdown for slide
$("#slideshow").attr("timeStop", "true");
window.clearTimeout(myInterval);
});
// Start timer on mouse up
$("#slideshow img").mouseup(function() {
// Restart a new countdown for slide using stored time remaining value
tempTime = parseInt($("#slideshow").attr("time"));
myInterval = setTimeout(slideSwitch, tempTime);
$("#slideshow").attr("timeStop", "false");
});
img {
display: none;
border: 5px solid black;
}
img.active {
display: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slideshow" time="">
<img src="https://via.placeholder.com/150/fff">
<img src="https://via.placeholder.com/150/000" class="active">
<img src="https://via.placeholder.com/150/f00">
<img src="https://via.placeholder.com/150/0f0">
<img src="https://via.placeholder.com/150/00f">
</div>
<p>Remaining: <span id="timerLabel"></span> ms</p>

Replace background image given an array of images

I am trying to set a background image rotation for a div with a image already in it, doesn't seem to change anything, thought I would check if someone could see the problem since no errors come up.
<script>
$( document ).ready(function() {
setInterval(function() {
var tips = [
"header.jpg",
"header2.jpg",
"header3.jpg",
"header4.jpg",
"header5.jpg",
];
var i = 0;
if (i == tips.length) --i;
$('.containercoloring').fadeTo('slow', 0.3, function()
{
$(this).css('background-image', 'url(' + tips[i] + ')');
}).delay(1000).fadeTo('slow', 1);
i++;
}, 5 * 1000);
});
</script>
<body>
<div class="containercoloring"> </div>
</body>
Below is the working(updated) code. I hope you are importing jquery lib separately.
<script>
$(document).ready(function() {
var i = 0;
setInterval(function() {
var tips = [
"header.jpg",
"header2.jpg",
"header3.jpg",
"header4.jpg",
"header5.jpg"
];
var imageIndex = ++i % tips.length;
$('.containercoloring').fadeTo('slow', 0.3, function() {
$(this).css('background-image', 'url(' + tips[imageIndex] + ')');
}).delay(1000).fadeTo('slow', 1);
}, 5 * 1000);
});
</script>
<body>
<div class="containercoloring" style="height: 100px;">Image Container</div>
</body>
You can test here in this jsfiddle - https://jsfiddle.net/nbq9f6bg/
Hope it helps!
So there were a couple of notes I had about your example. Please see the comments below. I used background color and removed the transitions to show it easier.
// declare variables
var tips = [
"#ff9000",
"#ff0000",
"#0099ff"
];
// counter
var i = 0;
// direction
var direction = 'forwards';
// time in between intervals
var timer = 2000;
function changeBackground() {
// Check the length minus 1 since your counter starts at 0
if (i == (tips.length - 1)) {
direction = 'backwards';
} else if(i == 0) {
// only set the direction back to forwards when the counter is 0 again
direction = 'forwards';
}
$('.containercoloring').css('background-color', tips[i]);
// add or subtract based on the direction
if(direction == 'forwards') {
i++;
} else {
i--;
}
}
$( document ).ready(function() {
// save interval to a variable so you can stop it later
var theInterval = setInterval(changeBackground, timer);
// run the function since the interval will take 2000ms to execute
changeBackground();
});
.containercoloring {
height: 100px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="containercoloring"> </div>

I want to create image gallery with infinite loop using jquery

I want to create an image gallery, I wrote for a slideshow, but I don't know how to code for the previous and next buttons. These should work like an infinite loop (last image jumps back to the first).
How should I get started? This is what I have so far:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#play").click(function () {
$("#img1").fadeOut(2000);
$("#img2").fadeIn();
$("#img2").fadeOut(4000);
$("#img3").fadeIn();
});
});
</script>
<body>
<div id=outer>
<div id=inner>
<img id="img1" src="img1.jpg"/>
<img id="img2" src="img2.jpg" style="display:none"/>
<img id="img3" src="img3.jpg" style="display:none"/>
</div>
<div id=button>
<button id="bwd"><<</button>
<button id="play"><></button>
<button id="fwd">>></button>
</div>
</div>
</body>
You can use setInterval() .
This link can help you to understand much more
Call function with setInterval in jQuery?
may be this can help you too :
http://jquery.malsup.com/cycle/
you're going to want to use the javascript timing function. Something like:
$('#play').click(function(){
window.setInterval(function(){
if($('#img1').is(:visible)){
$("#img2").show()
$("#img1").hide()
}
if($('#img2').is(:visible)){
$('#img3').show()
$('#img2').hide()
}
if($('#img3').is(:visible)){
$('#img1').show()
$('#img3').hide()
}
}, 1000);
});
You can also condense this logic down, but this gets you the basic idea. Then if you look carefully the functions for next is already in the code and it can be extracted out and reuses. Once you have the next function it's pretty straight forward that the back function will be the exact opposite.
To answer your question below you can change the img's to have the same class and then apply show and hide based on which one is visible and the image immediately after the visible one:
#find the one currently being shown
$(".images:visible")
#find the one after the visible one
$(".images:visible").next()
#keep an id on the last image so that you can do something like
if($('.images:visible') == $('#last_image')){
$('.images').first().show()
}
Hi i have created Carousel without using any third party plugin.If you want please refer.Reference Link
Js Code is.
$(document).ready(function () {
var currentPosition = 0;
var slideWidth = 300;
var slides = $('.slide');
var numberOfSlides = slides.length;
var timer = 3000;
var img1, img2;
var sliderLink = $("#slider a");
var direction = 1;
// Remove scrollbar in JS
$('#slidesContainer').css('overflow', 'hidden');
// Wrap all .slides with #slideInner // Float left to display horizontally, readjust .slides width
slides.wrapAll('<div id="slideInner"></div>').css({
'float': 'left',
'width': slideWidth
});
// Set #slideInner width equal to total width of all slides
$('#slideInner').css('width', slideWidth * numberOfSlides);
// Insert left and right arrow controls in the DOM
$('#slideshow').prepend('<span class="control" id="leftControl">Move left</span>').append('<span class="control" id="rightControl">Move right</span>');
// Hide left arrow control on first load
// manageControls(currentPosition);
// manageSlide();
// Create event listeners for .controls clicks
$('#rightControl').bind('click', rightControl);
$('#leftControl').bind('click', leftControl);
function leftControl() {
var butonid = 0;
direction = 0;
$("#slideInner").stop();
$("#slideInner").dequeue();
$('#timer').stop();
$('#timer').dequeue();
$('#leftControl').unbind('click');
manageSlide(0, direction);
setTimeout(function () {
$('#leftControl').bind('click', leftControl);
}, timer, null);
}
function rightControl() {
var butonid = 1;
direction = 1;
$("#slideInner").stop();
$("#slideInner").dequeue();
$('#timer').stop();
$('#timer').dequeue();
$('#rightControl').unbind('click');
manageSlide(0, direction);
setTimeout(function () {
$('#rightControl').bind('click', rightControl);
}, timer, null);
}
var slideIndex = 0;
var data = $("#slideInner .slide").toArray();
$("#slideInner").empty();
function manageSlide(auto, idButtonid) {
$("#slideInner").empty();
// console.log(slideIndex);
if (idButtonid == 0) {
$("#slideInner").css({ 'marginLeft': "-300px" });
$(data).each(function (index) {
// if (index == slideIndex - 1) {
// $(this).show();
// } else {
$(this).hide();
// }
});
$(data[slideIndex - 1]).show();
if (slideIndex == numberOfSlides - 1) {
slideIndex = 0;
img1 = data[0];
img2 = data[numberOfSlides - 1];
$("#slideInner").append(img1);
$("#slideInner").append(img2);
$(img2).show();
$(img1).show();
} else {
img1 = data[slideIndex];
img2 = data[slideIndex + 1];
$("#slideInner").append(img2);
$("#slideInner").append(img1);
$(img1).show();
$(img2).show();
slideIndex = slideIndex + 1;
}
$('#slideInner').animate({
'marginLeft': "0px"
}, 'slow', function () {
$('#timer').animate({
opacity: 1
}, timer, function () {
console.log('leftControl');
manageSlide(1, direction);
});
});
}
// right move here
else if (idButtonid == 1) {
$("#slideInner").css({ 'marginLeft': "0px" });
$(data).each(function (index) {
if (index == slideIndex + 1) {
$(this).show();
} else {
$(this).hide();
}
});
if (slideIndex == numberOfSlides - 1) {
slideIndex = 0;
img1 = data[0];
img2 = data[numberOfSlides - 1];
$("#slideInner").append(img2);
$("#slideInner").append(img1);
$(img2).show();
$(img1).show();
} else {
img1 = data[slideIndex];
img2 = data[slideIndex + 1];
$("#slideInner").append(img1);
$("#slideInner").append(img2);
$(img1).show();
$(img2).show();
slideIndex = slideIndex + 1;
}
$('#slideInner').animate({
'marginLeft': slideWidth * (-1)
}, 'slow', function () {
console.log('rightControl');
$('#timer').animate({
opacity: 1
}, timer, function () {
manageSlide(1, direction);
});
});
}
if (auto == 1) {
sliderLink.each(function () {
$(this).removeClass();
if ($(this).text() == (slideIndex + 1)) {
$(this).addClass('active');
}
});
}
auto = 1;
}
$("#slider a").click(function () {
sliderLink.each(function () {
$(this).removeClass();
});
slideIndex = $(this).addClass('active').text() - 1;
$('#timer').stop();
$('#timer').dequeue();
$("#slideInner").stop();
$("#slideInner").dequeue();
manageSlide(0, direction);
});
manageSlide(1, direction);
});
Demo Link
Hope it helps you.

Categories