How can I stop/pause a function from another function? - javascript

I have a simple jquery-ui slider which I am continuously automatically looping through values. I successfully have a button which starts the movement, but I forget how I can pause/stop the movement when another button is pressed? I know this is something really simple, but am having an absolute mind blank and google is not giving me what I want. (probably because i'm searching for the wrong wording). What can do I put in the pauseSlider function to ... pause the slider!
function scrollSlider() {
var slideValue;
slideValue = $("#slider").slider("value");
if (slideValue >= 0) {
if (slideValue == 2013) {
slideValue = -1;
}
$("#slider").slider("value", slideValue + 1);
console.log($("#slider").slider("value"));
setTimeout(scrollSlider, 1000);
}
}
$('#startSlider').click(function() {
scrollSlider();
});
$('#pauseSlider').click(function() {
//What do I put in here?
});

setTimeout returns a random number which you'll have to store in a variable and then use it to clear the setTimeout in $('#pauseSlider')'s click handler.
var id;
function scrollSlider() {
// (...) code
id = setTimeout(scrollSlider, 1000);
// (...) more code
}
$('#pauseSlider').click(function() {
clearTimeout(id);
});

Related

Change background images using setTimeout

I have 31 images and I want to display them one after another as the background of a div. I only want it to change when the user hovers over the div. My problem right now is that it just flips through all the images really fast. I am attempting to use setTimeout, but it isn't working. How can I make the delay work?
The name of the div is About_Me_Block and the images are called frame1.gif,frame2.gif ...etc
Here is my code:
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
var counter = 0;
while (hoverAnimate[0]) {
console.log(counter);
setTimeout(changeImg(counter), 1000);
counter++;
if (counter === 32)
hoverAnimate[0] = false;
}
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
setTimeout doesn't wait for the function to end, it works lile threading in other languages.
To achieve a what you want, you need to call setTimeout from the changeImg function.
var counter = 0;
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
counter = 0;
changeImg();
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
function changeImg() {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
counter++;
if (counter < 32 && hoverAnimate[0]) {
setTimeout(changeImg, 1000);
} else {
hoverAnimate[0] = false;
}
}
the reason they happen all at once is because while statement doesn't have delay, so all setTimeout will be set up at the same time, thus, calling changeImg all at once.
To solve this problem, you can replace setTimeout with setInterval. Instead of using while, you can just call setInterval like
var counter = 0;
var myTimer = setInterval(changeImg, 1000);
and update counter inside changeImg every time it gets called. After looping, don't forget to
clearInterval(myTimer)
It seems you need to read up on how setTimeout works. It essentially places a reminder to run a function after a given amount of milliseconds have passed. So, when you do setTimeout(changImg(counter), 1000) you are calling changImg(counter) which returns undefined. Therein producing this setTimeout(undefined, 1000) which is why it flips really fast.
So, you can use bind to allow the function to be called later with that parameter built in. Also, make sure you remove the reminders once done with clearTimeout.
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = false, id;
function loop(counter) {
if(hoverAnimate || counter < 32) {
changeImg(counter);
id = setTimeout(loop.bind(this, counter++), 1000);
}
}
$('#About_Me_Block').mouseenter(function() {
hoverAnimate = true;
id = setTimeout(loop.bind(this, 0), 1000);
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate = false;
// Don't want a reminder for a random counter to wake up.
clearTimeout(id);
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
Two methods for timers - setTimeout and SetInterval (single / repeating)
// setInterval is also in milliseconds
var intervalHandle = setInterval(<yourFuncToChangeImage>,5000);
//this handle loop and make example loop stop
yourelement.yourEvent = function() {
clearInterval(intervalHandle);
};

Why doesn't my mouseOver functions work?

The game is quite simple you click on the start button to begin then move your mouse along the track until you reach the end then the timer stops and shows you the score. If you go out of the track you get a score of zero.
Why don't my mouseOver functions work?
Link to my full code: http://www.codecademy.com/TictacTactic/codebits/AQBK4L/edit
Thank you in advance!
var score = 1000;
var timer = setInterval(countDown(), 1000);
$(document).ready(function() {
$('#start').click(function() {
$('#game').mouseover(function() {
stopTimer();
score = 0
$('#points').html(score)
});
$('#end').mouseover(function() {
stopTimer()
$('#points').html(score)
});
});
});
function countDown() {
score = score - 1;
}
function stopTimer() {
clearInterval(timer);
}
Most events are in lowercase, like mouseover, mouseout etc. There are also others that have capitals, like DOMContentLoaded. Most (if not all) programming languages are case-sensitive, watch out for these.
Try this
var clicked = false;
$('#start').click(function() {
if(!clicked){
clicked = true;
}
});
$("#game").hover(function(){
if(clicked){
stopTimer();
score = 0;
$("#points").html(score);
}
});
$("#end").hover(function(){
if(clicked){
stopTimer();
$("#points").html(score);
}
});
Then later if you don't want the hover event to work just set clicked to false I.E : clicked = false;

JQuery not executing within a For loop

Im a JQuery noob trying to write a simple jQuery code to get a text to blink three times. My initial code was as follows:
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
}
});
But since I probably meddled in forces I could not comprehend, the above code made the text blink only once. I read up on closures and got convinced that the below code could make a change. Unfortunately, it doesnt.
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
(function (i) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
})(i);
}
});
Can anyone tell me whats going on here?
You need make use of the animation queue
var $welcome = $("#welcome").click(function () {
var i = 1;
//clear previous animations
$welcome.stop(true, true);
while (++i < 10) {
$welcome.fadeOut("slow").fadeIn("slow");
}
});
Demo: Fiddle
Fading in and out takes some time, and you have to wait for your animation to be over before you can run the next one.
The provided answers solve your problem since jQuery is clever enough to bufferize your animation queue, but it may creates even more confusion for begginers, and also if you want to do something else between the fading animations, you can't rely on it anymore.
You then have to write your code on what is called an asynchronous recursive way (woah). Simply trying to understand that snippet may help you a lot with javascript general programming.
function blink(nbBlinks) {
// Only blink if the nbBlinks counter is not zero
if(nbBlinks > 0) {
$('#welcome').fadeOut('slow', function() {
// Do stuff after the fade out animation
$(this).fadeIn('slow', function() {
// Now we're done with that iteration, blink again
blink(nbBlinks-1);
})
});
}
}
// Launch our blinking function 10 times
blink(10);
This works perfectly. Demo http://jsfiddle.net/X5Qy3/
$("#welcome").click(function () {
for (var x = 0; x < 3; x += 1) {
$("#welcome").fadeOut("slow");
$("#welcome").fadeIn("slow");
}
});
Also, if you know how many times you want to do something. You should use a For Loop. While Loops are for when you don't know how many times you want it to run.
Set in queue
$("#welcome").click(function () {
var i = 1;
//clear animations whcih are running at that time
$(this).stop(true, true);
while (++i < 10) {
$(this).fadeOut("slow").fadeIn("slow");
}
});
You can not use jQuery delay function inside a looping/iteration hence you have to user closures:
$(document).ready(function(){
$(".click1").click(function () {
for (i=0;i<=10;i++) {
setTimeout(function(x) {
return function() {
$("#wrapper").fadeOut("slow", function () { $("#wrapper").fadeIn("slow"); })();
};
}(i), 1000*i);
}
});
});
<div id="wrapper"></div><div class="click1">click</div>
You can later change the count how many times you want to blink the <div>.

How to create a looped animation with JQuery

I have been sitting on this for a few hours and cannot figure this out. I am trying to create an slideshow (3 slides) that loops endlessly. Each slide is a li inside #slideshow. I have walked through this with a debugger and all variables get set correctly, but I don't understand why the animations dont actually happen. I have this which ends up displaying all images on the page:
$(document).ready(function() {
$slideshow = $('#slideshow');
$slideshowItems = $slideshow.find('li');
$slideshowItems.hide();
nextI = function(x) {
if ((x+1) < $slideshowItems.length) {
return x+1;
}
else {
return 0;
}
}
animation = function(i) {
$slideshowItems.eq(i).fadeIn(500).delay(1000).fadeOut(500, animation(nextI(i)));
}
animation(0);
If I do:
$slideshowItems.eq(0).fadeIn(500).delay(1000).fadeOut(500,
$slideshowItems.eq(1).fadeIn(500).delay(1000).fadeOut(500,
$slideshowItems.eq(2).fadeIn(500).delay(1000).fadeOut(500));
This works as expected, but it seems ugly and does not loop.
Any idea why I can't get this to work? I feel it is something with my expectations of how JQuery/ JS modifies the DOM or the sequence that the browser uses to execute animations. Thank you for the help!
var $slideshowItems = $('#slideshow').find('li'),
i = 0;
(function loop() {
$slideshowItems.eq( i ).fadeIn(500).delay(1000).fadeOut(500, loop);
i = ++i % $slideshowItems.length;
})();
JSFIDDLE DEMO
You should specify a callback method but your "animation(nextI(i))" returns nothing, so nothing remains to do after the fade out is complete.
Something like this I think will work:
var animation = function(i) {
$slideshowItems.eq(i).fadeIn(500).delay(1000).fadeOut(500, function (){
animation(nextI(i));
});
}
I would try setting that as a function and then using setInterval:
setInterval(function(){
$slideshowItems.eq(0).fadeIn(500).delay(1000).fadeOut(500, function() {
$slideshowItems.eq(1).fadeIn(500).delay(1000).fadeOut(500, function() {
$slideshowItems.eq(2).fadeIn(500).delay(1000).fadeOut(500);
});
});
}, 6000); // 6000 milliseconds before loops

jQuery function attr() doesn't always update img src attribute

Context: On my product website I have a link for a Java webstart application (in several locations).
My goal: prevent users from double-clicking, i. e. only "fire" on first click, wait 3 secs before enabling the link again. On clicking, change the link image to something that signifies that the application is launching.
My solution works, except the image doesn't update reliably after clicking. The commented out debug output gives me the right content and the mouseover callbacks work correctly, too.
See it running here: http://www.auctober.de/beta/ (click the Button "jetzt starten").
BTW: if anybody has a better way of calling a function with a delay than that dummy-animate, let me know.
JavaScript:
<script type="text/javascript">
<!--
allowClick = true;
linkElements = "a[href='http://www.auctober.de/beta/?startjnlp=true&rand=1249026819']";
$(document).ready(function() {
$('#jnlpLink').mouseover(function() {
if ( allowClick ) {
setImage('images/jetzt_starten2.gif');
}
});
$('#jnlpLink').mouseout(function() {
if ( allowClick ) {
setImage('images/jetzt_starten.gif');
}
});
$(linkElements).click(function(evt) {
if ( ! allowClick ) {
evt.preventDefault();
}
else {
setAllowClick(false);
var altContent = $('#jnlpLink').attr('altContent');
var oldContent = $('#launchImg').attr('src');
setImage(altContent);
$(this).animate({opacity: 1.0}, 3000, "", function() {
setAllowClick(true);
setImage(oldContent);
});
}
});
});
function setAllowClick(flag) {
allowClick = flag;
}
function setImage(imgSrc) {
//$('#debug').html("img:"+imgSrc);
$('#launchImg').attr('src', imgSrc);
}
//-->
</script>
A delay can be achieved with the setTimeout function
setTimeout(function() { alert('something')}, 3000);//3 secs
And for your src problem, try:
$('#launchImg')[0].src = imgSrc;
Check out the BlockUI plug-in. Sounds like it could be what you're looking for.
You'll find a nice demo here.
...or just use:
$(this).animate({opacity: '1'}, 1000);
wherever you want in your code, where $(this) is something that is already at opacity=1...which means everything seemingly pauses for one second. I use this all the time.
Add this variable at the top of your script:
var timer;
Implement this function:
function setFlagAndImage(flag) {
setAllowClick(flag);
setImage();
}
And then replace the dummy animation with:
timer = window.setTimeout(function() { setFlagAndImage(true); }, 3000);
If something else then happens and you want to stop the timer, you can just call:
window.clearTimeout(timer);

Categories