jQuery setInterval 函数可以自行停止吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5760892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a setInterval function stop itself?
提问by Justin808
I have a jsFiddleup with an example to work from.
我有一个jsFiddle和一个例子。
$().ready(function() {
$('.test').each(function() {
$this = $(this);
$this.data('Worker', function() {
$('#stop').html((parseInt($('#stop').html()) + 1))
})
setInterval($this.data('Worker'), 100);
});
$('#stop').click(function() {
// I want the worker function to stop being triggered here
$('.test').remove();
});
});
What I would like to do is attach a worker function to an element in the DOM so that when the element is removed, the worker function stops.
我想做的是将一个辅助函数附加到 DOM 中的一个元素上,这样当元素被移除时,辅助函数就会停止。
Is something like this possible?
这样的事情可能吗?
采纳答案by ?ime Vidas
Here you go:
干得好:
var stopBtn = $( '#stop' );
$( '.test' ).each(function ( i, elem ) {
var tid = setInterval(function () {
if ( elem.parentNode ) {
stopBtn.html(function ( i, num ) { return parseInt(num,10) + 1; });
} else {
clearInterval( tid );
}
}, 1000);
});
stopBtn.click(function () {
$( '.test' ).remove();
});
Explanation:
解释:
First of all we need a closure - the interval function needs to know which test-DIV is its "owner", ergo, we need to pass a reference to the DIV into the interval function. In my code, that reference is stored in the elem
variable, which is available inside the interval function because of closure. So, the interval function checks whether or not its "owner" DIV is still attached to the DOM (by examining its parent node). If it is, the stop-button is incremented. If it's not, the interval is cleared. However, in order to be able to clear the interval, we require its timer ID. We have this ID, because we stored it inside the "tid" variable (the setInterval call returns the timer ID).
首先我们需要一个闭包——区间函数需要知道哪个 test-DIV 是它的“所有者”,因此,我们需要将 DIV 的引用传递给区间函数。在我的代码中,该引用存储在elem
变量中,由于闭包,该变量在区间函数内可用。因此,间隔函数检查其“所有者” DIV 是否仍附加到 DOM(通过检查其父节点)。如果是,停止按钮增加。如果不是,则清除该间隔。但是,为了能够清除间隔,我们需要它的计时器 ID。我们有这个 ID,因为我们将它存储在“tid”变量中(setInterval 调用返回计时器 ID)。
Live demo:http://jsfiddle.net/simevidas/ZjY7k/15/
回答by Andrius Naru?evi?ius
Late to the party, but I solved this way:
聚会迟到了,但我是这样解决的:
var id = setInterval(function()
{
if(some_condition)
{
clearInterval(id);
}
}, 1000);
Definitely the simplest way out of all: no unnecessary storing, no tricks.
绝对是最简单的方法:没有不必要的存储,没有技巧。
回答by Seizefire
Another way that you can remove intervals, is using the clearInterval inside the interval.
您可以删除间隔的另一种方法是在间隔内使用 clearInterval 。
window.setInterval(function(){
// Do all your stuff here
if(/*something something*/){
window.clearInterval(this);
alert("The interval didn't clear");
}
}, /*However long*/);
If the interval doesn't clear, it will show an alert saying, "The interval didn't clear". Otherwise, the interval sucessfully cleared.
如果间隔没有清除,它会显示一个警告,说“间隔没有清除”。否则,间隔成功清除。
回答by Steven Lu
I suspect that the proper way to implement a "self-terminating" interval is to implement the interval via a series of timeouts.
我怀疑实现“自终止”间隔的正确方法是通过一系列超时来实现间隔。
In semi-pseudocode:
在半伪代码中:
setTimeout(function repeat() {
if (continue_to_run) // this code here may cause timing to be inaccurate
setTimeout(repeat, interval_duration);
do_task_on_interval();
}, 0)
This repeating timer cleans up after itself.
这个重复的计时器会自行清理。
回答by zneak
It's a little-known fact, but setInterval
returns a value that you can use with clearInterval
to cancel the interval.
这是一个鲜为人知的事实,但会setInterval
返回一个值,您可以使用它clearInterval
来取消间隔。
var result = setInterval(function, delay);
// at some point later...
clearInterval(result);
回答by Michael Dean
Use clearInterval:
使用 clearInterval:
$().ready(function () {
$('.test').each(function () {
$this = $(this);
$this.data('Worker', function () { $('#stop').html((parseInt($('#stop').html()) + 1)) })
$this.data('intervalId', setInterval($this.data('Worker'), 100));
});
$('#stop').click(function () {
$('.test').each(function() { clearInterval($(this).data('intervalId')); }).remove();
});
});