javascript - Watching setTimeout loops so that only one is running at a time -
i'm creating content rotator in jquery. 5 items total. item 1 fades in, pauses 10 seconds, fades out, item 2 fades in. repeat.
simple enough. using settimeout can call set of functions create loop , repeat process indefinitely.
i want add ability interrupt rotator @ time clicking on navigation element jump directly 1 of content items.
i started going down path of pinging variable (say every half second) check see if navigation element clicked and, if so, abandon loop, restart loop based on item clicked.
the challenge ran how ping variable via timer. solution dive javascript closures...which little on head need delve more.
however, in process of that, came alternative option seems better performance-wise (theoretically, @ least). have sample running here:
(it's using console.log have firebug running)
sample script:
$(document).ready(function(){ var loopcount = 0; $('p#hello').click(function(){ loopcount++; dothatthing(loopcount); }) function dothatotherthing(currentloopcount) { console.log('dothatotherthing-'+currentloopcount); if(currentloopcount==loopcount){ settimeout(function(){dothatthing(currentloopcount)},5000) } } function dothatthing(currentloopcount) { console.log('dothatthing-'+currentloopcount); if(currentloopcount==loopcount){ settimeout(function(){dothatotherthing(currentloopcount)},5000); } } })
the logic being every click of trigger element kick off loop passing variable equal current value of global variable. variable gets passed , forth between functions in loop.
each click of trigger increments global variable subsequent calls of loop have unique local variable.
then, within loop, before next step of each loop called, checks see if variable has still matches global variable. if not, knows new loop has been activated ends existing loop.
thoughts on this? valid solution? better options? caveats? dangers?
update:
i'm using john's suggestion below via cleartimeout option.
however, can't quite work. logic such:
var slidenumber = 0; var timeout = null; function startloop(slidenumber) { //... code here stuff here set slide based on slidenumber... slidefadein() } function continuecheck() { if (timeout != null) { // cancel scheduled task. cleartimeout(timeout); timeout = null; return false; } else { return true; } }; function slidefadein() { if (continuecheck){ // new loop hasn't been called yet proceed... $myslide.fadein(fade, function() { timeout = settimeout(slidefadeout,display); }); } }; function slidefadeout() { if (continuecheck){ // new loop hasn't been called yet proceed... slidenumber=slidenumber+1; $myslide.fadeout(fade, function() { //... code here check if i'm on last slide , reset #1... timeout = settimeout(function(){startloop(slidenumber)},100); }); } }; startloop(slidenumber);
the above kicks of looping.
i have navigation items that, when clicked, want above loop stop, restart new beginning slide:
$(mynav).click(function(){ cleartimeout(timeout); timeout = null; startloop(thisitem); })
if comment out 'startloop...' click event, it, indeed, stops initial loop. however, if leave last line in, doesn't stop initial loop. why? happens both loops seem run in parallel period.
so, when click navigation, cleartimeout called, clears it.
what should save handle returned settimeout
, clear cleartimeout
interrupt rotator.
var timeout = null; function dothatthing() { /* thing. */ // schedule next call. timeout = settimeout(dothatotherthing, 5000); } function dothatotherthing() { /* other thing. */ // schedule next call. timeout = settimeout(dothatthing, 5000); } function interruptthings() { if (timeout != null) { // never mind, cancel scheduled task. cleartimeout(timeout); timeout = null; } }
when navigation element clicked call interruptthings()
. nice part take effect , don't need polling or else complicated.
Comments
Post a Comment