问题
I'm fairly new to JavaScript/jQuery, but have made a script to change the background picture.
First Script
The first script version works fine and does the following:
- creates a setInterval timer that calls function backgroundChange() to run every 7 seconds
- decides the next picture URL
- sets the background picture
This works great, but the problem is when the website is live, on a slow connection the background picture doesn't load in time for the next timer change.
New Script
So the new version:
- creates a setTimeout timer that calls function backgroundChange() to run after 7 seconds
var theTimer = setTimeout(backgroundChange, 7000);
- clearsTimeout (surely I shouldn't have to run this?)
window.clearTimeout(theTimer);
- decides the next picture URL
- waits until the picture is loaded:
- then sets the background picture
- then adds a new setTimeout timer
$('#testImage').attr('src', imageText).load(function()
{
$('#backgroundTop').fadeIn(timeIn,function()
{
theTimer = setTimeout(backgroundTimer, 7000);
});
});
The problem is that the timer now seems to be called double the amount of times whenever the timer runs and exists in the .load function.
I havent purposely not posted my code yet, as I want to make sure my understanding is correct first, rather than someone just fixing my code.
Ta very much.
回答1:
You need to unbind the load handler before you add the next one, since they keep piling up as your code stands. With every iteration, you add an extra handler that does the exact same thing. Use unbind
to remove the old handler before you reattach:
$('#testImage').unbind('load');
回答2:
Instead of unbinding, you could use a JavaScript closure for the timer function. This will maintain a single timer that is reset every time it is called.
var slideTimer = (function(){
var timer = 0;
// Because the inner function is bound to the slideTimer variable,
// it will remain in score and will allow the timer variable to be manipulated.
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
Then in your code:
$('#testImage').attr('src', imageText).load(function() {
$('#backgroundTop').fadeIn(timeIn,function()
{
slideTimer(backgroundTimer, 7000);
});
});
There should be no need to clear or set the timer anywhere else in your code.
来源:https://stackoverflow.com/questions/14425171/javascript-settimeout-duplicates