我正在制作一个使用setTimeout
和clearTimeout
的简单fadeIn / fadeOut循环动画。到目前为止,这是我的代码:
HTML:
<p><span>loading...</span></p>
<a href="#" id="btn">STOP</a>
的Javascript(jQuery1.9.1):
var _timer;
var _timerArr = [];
var loaderBlink = function() {
$('p').find('span').fadeTo(200,.4).fadeTo(200,1,function() {
_timer = setTimeout(function() { loaderBlink() }, 200);
_timerArr.push(_timer);
//console.log('loading...');
});
};
var clearTimer = function() {
$.each(_timerArr, function(i,val) {
clearTimeout(val);
console.log(val);
});
$('#btn').remove();
$('p').fadeOut('fast');
return false;
};
$('#btn').on('click', function() {
clearTimer();
});
loaderBlink();
DEMO:http://jsfiddle.net/nori2tae/MW9E8/
问题在于,即使我将所有计时器推入阵列以便之后通过单击“停止”按钮清除它们,有时计时器也会停止并继续运行。
可能我不完全理解setTimeout
和clearTimeout
的概念。我需要一些解决方案,并帮助理解这两个功能。
答案 0 :(得分:2)
这是一个setIntevall版本:
编辑:它运行良好,但你必须使用函数loaderBlink()包装计时器;再次,错误地删除了它,还没有足够的咖啡。
var _timer;
_timer = setInterval(function () {
$('p').find('span').fadeTo(200,.4).fadeTo(200,1);
console.log('loading...');
}, 400);
var clearTimer = function() {
clearInterval(_timer);
$('#btn').remove();
$('p').fadeOut('fast');
return false;
};
$('#btn').on('click', function() {
clearTimer();
});
答案 1 :(得分:1)
保存对数组中所有定时器的引用没有多大意义 - 定时器没有连续运行,因此仅将最新的定时器存储在单个数组中就足够了。你只需要停止最后一个,其他一切都已经停止了。
我怀疑当动画运行时点击某个时刻计时器不会停止,所以按钮会停止除了尚未启动的计时器之外的所有计时器,因为动画队列仅在动画停止时启动它。
无论如何,如果没有计时器,这实际上会更简单,更可靠。
var blink = true;
var loaderBlink = function() {
if( blink ) {
$('p').find('span').delay( 200 ).fadeTo(200,.4).fadeTo(200,1,function() {
loaderBlink();
console.log('loading...');
});
}
};
$('#btn').on('click', function() {
blink = false;
$(this).remove();
$('p').stop().fadeOut('fast');
return false;
});
loaderBlink();
操作与原始代码略有不同:200毫秒延迟是在动画循环开始时而不是在它之后,但我认为这不是问题。 .stop()
确保循环不会重新开始。
答案 2 :(得分:1)
你解决这个问题的方法有点不对 - 你看到你定义的时间是200ms - 这段时间很短,在代码响应你的点击之前,下一个计时器会继续进行,所以有时候它的工作有时它不是。 同时保存数组中的所有interval_id没有任何意义,因为setTimeout只发生一次(与setInterval相反)。您需要做的是使用标志并关闭单个计时器ID:http://jsfiddle.net/MW9E8/2/
var _timer;
var _timerArr = [];
var fading;
var loaderBlink = function() {
if(fading){
$('p').find('span').fadeTo(200,.4).fadeTo(200,1,function() {
interval_id = setTimeout(function() { loaderBlink() }, 200);
// _timerArr.push(_timer);
console.log('loading...');
});
}
};
var clearTimer = function() {
/*
$.each(_timerArr, function(i,val) {
console.log(val);
});
*/
clearTimeout(interval_id);
fading = false;
// $('#btn').remove();
// $('p').fadeOut('fast');
return false;
};
$('#btn').on('click', function() {
clearTimer();
});
fading = true;
loaderBlink();
答案 3 :(得分:1)
如果你正在为动画使用jQuery,你可以继续使用jQuery来处理其他一切......不需要混合使用setIntervals
和setTimeouts
:
<强>拨弄强>
<强>标记强>
<span id="loading">Loading...</span>
<button id="stop">Stop!</button>
<强> JS 强>
$(function(){
var fadeLoading;
(fadeLoading = function(){
$('#loading:not(.stopped)')
.fadeTo(200,0.4)
.fadeTo(200,1, fadeLoading) /// you can just loop this
;
})();
$('#stop').click(function(){
$('#loading')
.addClass('stopped') /// add a class to stop new fade starting
.stop() /// stop existing animations
.fadeTo(200,1) /// fade loading up to 100%
;
});
});