mouseover image stuck in loop - javascript

I have been making this JavaScript code to display multiple images in one frame on mouse over.
But I get stuck in the setInterval loop and the images keep on changing although I exited the frame.
It is definitely stuck in the function change().
I can not find a way to exit this as I move my cursor.
Could you give me a hand?
let start = 0;
const imageChange = document.querySelector(".image");
imageChange.addEventListener("mouseover", set_time);
imageChange.addEventListener("mouseout", end);
function set_time() {
setInterval(change, 1500);
}
function change() {
if (start < 3) {
console.log(start);
imageChange.src = "/img/image" + start + ".jpg";
start++;
} else {
start = 0;
}
}
function end() {
start = 0;
imageChange.src = "/img/image" + start + ".jpg";
}

You need to use clearInterval to stop the continuous execution of the function.
let intvl;
function set_time() {
intvl = setInterval(change, 1500);
}
function change() {
if (start < 3) {
console.log(start);
imageChange.src = "/img/image" + start + ".jpg";
start++;
} else {
start = 0;
}
}
function end() {
start = 0;
clearInterval(intvl);
imageChange.src = "/img/image" + start + ".jpg";
}

Related

SetInterval running even after i clear it

Im having a little trouble fixing a problem i have with setInterval.
I have a function that runs when i click an element on my website that sets var pass = 1;
if you look in color1(); there is a set Interval that clears itself when pass > 0; so if pass = 1; then it should clear itself, it does, but only after running the interval one more time.
so it - runs setInterval, clears setInterval, then runs the rest of the code in setInterval. What i need, is for setInterval to clear without running the code again.
Thanks in advance
function color1() {
var pass = 1;
var counter = 2;
var animationSpeed = 800;
var $colorContent = '.color-container-1 .color-content-container'
var colorInterval = setInterval(function() {
if (pass > 0) {
clearInterval(colorInterval);
}
$($colorContent).fadeOut(0);
$(($colorContent + '-' + counter)).fadeIn(animationSpeed);
++counter
if (counter === $($colorContent).length + 1) {
counter = 1;
}
}, 3000);
}
It should be like below, you should return the function. Here you have cleared the interval but you haven't stopped the execution
var colorInterval = setInterval(function() {
if (pass > 0) {
clearInterval(colorInterval);
return; //stop here so that it doesn't continue to execute below code
}
$($colorContent).fadeOut(0);
$(($colorContent + '-' + counter)).fadeIn(animationSpeed);
++counter
if (counter === $($colorContent).length + 1) {
counter = 1;
}
}, 3000);

setInterval doesnt tigger inner script on first time run

Maybe I'm not properly understanding setInterval but I have made a kind of slideshow script, as below:
var i = 0;
setInterval(function() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
if(i == 5){
i = 0;
}
}, 4000);
This works, except for the first run - no slides will display for the first 4 seconds.
See Fiddle here: http://jsfiddle.net/vpa89snf/6/
Is there anyway I can trigger whats inside the setInterval function when it runs the first time round?
Use setTimeOut instead of setInterval for better performance, inspect the sample below:
Here is working jsFiddle.
var i = -1;
var totalSlide = $('.slide').length-1;
var slideTimer = 0;
function nextFrame() {
i == totalSlide ? i = -1 : i;
i++;
$('.slide').fadeOut(200);
$('.slide').eq(i).fadeIn(200);
slideTimer = setTimeout(nextFrame,4000);
}
$('#holder').addClass('isAni');
nextFrame();
// play / pause animation
$('#holder').click(function() {
if ( $(this).hasClass('isAni') ) {
$(this).removeClass('isAni');
clearTimeout(slideTimer);
}else{
$(this).addClass('isAni');
nextFrame();
}
});
You need to run the function and not wait for the 4 first seconds:
var i = 0;
function doSomething() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i = (i + 1) % 5;
}
$document.ready(function () {
setInterval(doSomething, 4000);
doSomething(); // run it!
});
JSFIDDLE.
This is how setInterval is executed. It runs your function after x milliseconds set as 2nd parameter.
What you have to do in order to show the first slide is to have the 1rst slide fadein like below:
var i = 0;
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
setInterval(function() {
...
}, 4000);

Sequentially highlighting divs using javascript

I'm trying to create kind of runway of lights and here's what it looks like now
http://jsfiddle.net/7NQvq/
var divs = document.querySelectorAll('div');
var index = 0;
setInterval(function(){
if(index > divs.length+20){
index = 0;
}
if(divs[index-1]){
divs[index-1].className = '';
}
if(divs[index]){
divs[index].className = 'active';
}
index++;
}, 50);
What I don't like about it is that it's completely inflexible and hard to adjust. Furthermore it also runs additional 20 empty cycles which is wrong. Is there a better way to achieve it (preferrably pure JS)?
It seemes that there must be some combination of setInterval and setTimeout but I just can't make it work.
I've made some adjustments to use a CSS animation rather than messing around with transitions and class toggling.
Updated Fiddle
All the JavaScript does now is define the animation delay for each dot.
You can adjust:
The animation delay - I just have i/10, but you could make it i/5, i/20... experiment!
The animation duration - it's set to 1s in my Fiddle, but try shorter and longer to see what happens
The 50% that indicates when the light has faded out
How about
function cycle(selector, cssClass, interval) {
var elems = document.querySelectorAll(selector),
prev = elems[0],
index = 0,
cssClassRe = new RegExp("\\s*\\b" + cssClass + "\\b");
if (elems.length === 0) return;
return setInterval(function () {
if (prev) prev.className = prev.className.replace(cssClassRe, "");
index %= elems.length;
elems[index].className += " " + cssClass;
prev = elems[index++];
}, interval);
}
and
var runwayIntval = cycle("div", "active", 100);
and at some point
clearInterval(runwayIntval);
See: http://jsfiddle.net/arNY8/1/
Of course you could argue that toggling a CSS class is a little limited. You could work with two callback functions instead: one to switch on a freely definable effect, one to switch it off:
function cycle(elems, enable, disable, interval) {
var prev = elems[0], index = 0;
if (elems.length === 0) return;
return setInterval(function () {
index %= elems.length;
if (prev) disable.call(prev);
enable.call(elems[index]);
prev = elems[index++];
}, interval);
}
and
var cycleIntval = cycle(
document.querySelectorAll("div"),
function () {
this.className += " active";
},
function () {
this.className = this.className.replace(/\s*\bactive\b/, "");
},
100
);

my jquery slider is running well but there is bug that it sometimes does'nt shows images on next or prev click

Found solution for the playing and stopping the slider.But problem is now with my next and prev links .these links some times does not shows any image.
my code is on the
http://jsfiddle.net/yogesh84/ftkLd/12/
var slides;
var cnt;
var amount;
var i;
var x;
var timer;
slides = jQuery('#my_slider').children();
cnt = jQuery('#counter');
amount = slides.length;
i=amount;
cnt.text(i+' / '+amount);
function run_prev() {
jQuery(slides[i]).fadeOut(1000);
i--;
if (i <= 0) i = amount;
jQuery(slides[i]).fadeIn(1000);
// updating counter
cnt.text(i+' / '+amount);
}
x=0;
function run_next() {
// hiding previous image and showing next
jQuery(slides[x]).fadeOut(1000);
x++;
if (x >= amount) x = 0;
jQuery(slides[x]).fadeIn(1000);
cnt.text(x+1+' / '+amount);
}
/***********start and stop functions***************/
function run() {
// hiding previous image and showing next
jQuery(slides[x]).fadeOut(1000);
x++;
if (x >= amount) x = 0;
jQuery(slides[x]).fadeIn(1000);
timer = setTimeout(run,2000);
}
function MySlider() {
timer = setTimeout(run,2000);
}
function stoper() {
clearTimeout(timer);
}
/***********end start and stop functions***************/
function slide_show(){
var timer;
if(jQuery('#slide_show').html()=='Play Slideshow')
{
jQuery('#slide_show').html('Stop Slideshow');
MySlider();
}
else
{
jQuery('#slide_show').html('Play Slideshow');
stoper()
}
}
// custom initialization
jQuery('#prev2').on("click",run_prev);
jQuery('#next2').on("click",run_next);
jQuery('#slide_show').on("click",slide_show);
I think you forgot to set timer
You declare at the top: timer but it is never filled.
So i think you should do:
timer = setTimeout( run, inetrval );
Also take the function outside of Run()
function run() {
}
if ( inetrval > 0 ) {
alert( inetrval );
run();
timer = SetTimeOut( run, inetrval )
}

JavaScript how to reverse this animation, after click another link

$('#home').click(doWork);
function doWork() {
var index = 0;
var boxes = $('.box1, .box2, .box3, .box4, .box5, .box6');
function start() {
boxes.eq(index).addClass('animated');
++index;
setTimeout(start, 80);
};
start();
}
when i click a link, this animation start . And after end the animation, i need to reverse this animation, after click another link.
Here's code that allows you to start the process, as well as interrupt it to do the reverse:
(function () {
"use strict";
var doWork,
index,
boxes,
numBoxes,
workerTO;
index = 0;
boxes = $(".box1, .box2, .box3, .box4, .box5, .box6");
numBoxes = boxes.length;
doWork = function (changer, reverse) {
var direction, worker;
clearTimeout(workerTO);
direction = reverse ? -1 : 1;
worker = function () {
if (reverse) {
if (index < 0) {
index = 0;
return;
}
} else {
if (index >= numBoxes) {
index = numBoxes - 1;
return;
}
}
console.log(index);
changer(boxes.eq(index));
index += direction;
workerTO = setTimeout(worker, 80);
};
worker();
};
$("#home").click(function () {
doWork(function (el) {
el.addClass("animated");
});
});
$("#home2").click(function () {
doWork(function (el) {
el.removeClass("animated");
}, true);
});
}());
DEMO: http://jsfiddle.net/NcdZT/1/
I'm sure some things could be condensed and made more efficient (like the if statements), but this seems readable and achieves what you want.
Keeping track of the setTimeout allows the process to be interrupted. If you increased the timeout from 80 to something more noticeable (or if you click fast enough), you would see that the "animation" can be reversed midway through.

Categories