javascript - Clearing multiple timeouts properly -
i've been struggling past day trying solve one.
i'm trying funky text effects going, glorified string creation. writes line bit billboard , i've used settimeout. thing put in function can reuse , call multiple times on different elements.
the problem need update text maybe halfway new text. clear timeout, unless timer variable outside scope doesn't clear.
i can't have outside function because of practicality; i'm not sure how many times going called , feels wrong declare 20 time variables outside function.
here's code working correctly on 1 item (click multiple times interrupt , restart)
var t; function writestats(str,dest) { var options = { "step" : 8, // how many times should letters changed "fps" : 25, // frames per second "text" : "" // use text instead of contents } function randomchar(type){ var pool = ""; if (type == "lowerletter"){ pool = "abcdefghijklmnopqrstuvwxyz0123456789"; } else if (type == "upperletter"){ pool = "abcdefghijklmnopqrstuvwxyz0123456789"; } else if (type == "symbol"){ pool = ",.?/\\(^)![]{}*&^%$#'\""; } var arr = pool.split(''); return arr[math.floor(math.random()*arr.length)]; } str = str.split(''); var types = [], letters = []; for(var i=0;i<str.length;i++){ var ch = str[i]; if(ch == " "){ types[i] = "space"; continue; } else if(/[a-z]/.test(ch)){ types[i] = "lowerletter"; } else if(/[a-z]/.test(ch)){ types[i] = "upperletter"; } else { types[i] = "symbol"; } letters.push(i); } cleartimeout(t); (function shuffle(start){ // code run options.fps times per second // , updates contents of page element var i, len = letters.length, strcopy = str.slice(0); // fresh copy of string if(start>len){ return; } // work gets done here for(i=math.max(start,0); < len; i++){ // start argument , options.step limit // characters working on @ once if( < start+options.step){ // generate random character @ position strcopy[letters[i]] = randomchar(types[letters[i]]); } else { strcopy[letters[i]] = ""; } } //el.text(strcopy.join("")); el = strcopy.join(""); //console.log(el); $('.'+dest).text(el); t = settimeout(function(){ shuffle(start+1); },500/options.fps); })(-options.step); } $(document).ready(function(){ $(document).click(function(){ writestats('this sentence great one','t1'); }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <div class="t1"></div> <div class="t2"></div>
if bring t variable inside function doesn't work before:
function writestats(str,dest) { var t; var options = { "step" : 8, // how many times should letters changed "fps" : 25, // frames per second "text" : "" // use text instead of contents } function randomchar(type){ var pool = ""; if (type == "lowerletter"){ pool = "abcdefghijklmnopqrstuvwxyz0123456789"; } else if (type == "upperletter"){ pool = "abcdefghijklmnopqrstuvwxyz0123456789"; } else if (type == "symbol"){ pool = ",.?/\\(^)![]{}*&^%$#'\""; } var arr = pool.split(''); return arr[math.floor(math.random()*arr.length)]; } str = str.split(''); var types = [], letters = []; for(var i=0;i<str.length;i++){ var ch = str[i]; if(ch == " "){ types[i] = "space"; continue; } else if(/[a-z]/.test(ch)){ types[i] = "lowerletter"; } else if(/[a-z]/.test(ch)){ types[i] = "upperletter"; } else { types[i] = "symbol"; } letters.push(i); } cleartimeout(t); (function shuffle(start){ // code run options.fps times per second // , updates contents of page element var i, len = letters.length, strcopy = str.slice(0); // fresh copy of string if(start>len){ return; } // work gets done here for(i=math.max(start,0); < len; i++){ // start argument , options.step limit // characters working on @ once if( < start+options.step){ // generate random character @ position strcopy[letters[i]] = randomchar(types[letters[i]]); } else { strcopy[letters[i]] = ""; } } //el.text(strcopy.join("")); el = strcopy.join(""); //console.log(el); $('.'+dest).text(el); t = settimeout(function(){ shuffle(start+1); },500/options.fps); })(-options.step); } $(document).ready(function(){ $(document).click(function(){ writestats('this sentence great one','t1'); }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <div class="t1"></div> <div class="t2"></div>
if run snippet you'll see doesn't work anymore. clicking repeatedly show old sentence still there , gets overwritten. how can working clearing timeout correctly inside function?
i thought "t" variable local each function , separate instance of have been created?
thanks!
ok, here's dumbed down version (maybe amount of code before) correct version
var starr = [ 'bloop boop', 'cammy shadow', 'i cauliflower', 'bro, kick u hard', 'like measels? dont.', 'eat fish , pie' ]; var timer; function writestats(str, dest) { $('.'+dest).text(''); var options = { "step" : 8, // how many times should letters changed "fps" : 25, // frames per second "text" : "" // use text instead of contents } str = str.split(''); cleartimeout(timer); var ll = ''; (function shuffle(start){ // code run options.fps times per second // , updates contents of page element var i, len = str.length, el; if(start>=len){ return; } ll = ll + str[start]; $('.'+dest).text(ll); timer = settimeout(function(){ shuffle(start+1); },1500/options.fps); })(0); } $(document).ready(function(){ var index = 0; $(document).click(function(){ writestats(starr[index],'t1'); if (index == 5) index = 0; else index++; }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> correct version <div class="t1">click anywhere multiple times</div>
not working version
var starr = [ 'bloop boop', 'cammy shadow', 'i cauliflower', 'bro, kick u hard', 'like measels? dont.', 'eat fish , pie' ]; function writestats(str, dest) { var timer; $('.'+dest).text(''); var options = { "step" : 8, // how many times should letters changed "fps" : 25, // frames per second "text" : "" // use text instead of contents } str = str.split(''); cleartimeout(timer); var ll = ''; (function shuffle(start){ // code run options.fps times per second // , updates contents of page element var i, len = str.length, el; if(start>=len){ return; } ll = ll + str[start]; $('.'+dest).text(ll); timer = settimeout(function(){ shuffle(start+1); },1500/options.fps); })(0); } $(document).ready(function(){ var index = 0; $(document).click(function(){ writestats(starr[index],'t1'); if (index == 5) index = 0; else index++; }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> not working version (please note moved timer declaration inside function) <div class="t1">click anywhere multiple times fast</div>
Comments
Post a Comment