【问题标题】:How do I clear all intervals?如何清除所有间隔?
【发布时间】:2011-12-26 11:57:19
【问题描述】:

我正在使用

varName = setInterval(function() { ... }, 1000);

在我正在编写的 jquery 插件中设置几个间隔,但是当插件重新加载时,我需要清除这些间隔。我尝试将它们存储在变量中,如下所示:

(function($){
$.mosaicSlider = function(el) {
    var base = this;        
    var transitionInterval, mainInterval;

...

base.init = function() {
    mainInterval = setInverval(function() { ... }, 1000);
}

base.grid = function() {
    this.transition() = function() {
         transitionInterval = setInterval(function(...) {
    }
}

base.init();

我尝试在 base.init() 函数中杀死这些间隔,如下所示:

clearInterval(transitionInterval);
clearInterval(mainInterval);

像这样:

window.oldSetInterval = window.setInterval;
window.setInterval = new function(func, interval) {  }

【问题讨论】:

标签: javascript jquery set


【解决方案1】:

您可以通过创建一个“什么都不做”的新计时器来找到“最高”计时器标识符(通过给它一个空函数来运行,计划在未来几十年运行),然后清除 ids 1 和该标识符,如下所示:

// Get a reference to the last interval + 1
const interval_id = window.setInterval(function(){}, Number.MAX_SAFE_INTEGER);

// Clear any timeout/interval up to that id
for (let i = 1; i < interval_id; i++) {
  window.clearInterval(i);
}

但是,请注意,这并不能保证起作用:HTML 标准does not actually prescribe 如何分配超时/间隔标识符,因此假设我们将获得对“最后一个间隔”的引用标识符 + 1" 仅仅是:一个假设。在给出这个答案时,大多数浏览器可能都是这样,但没有保证,即使在同一浏览器的下一个版本中,情况仍然如此。

【讨论】:

  • 这个 sn-p 确实有效,但它会引起一些奇怪的副作用。这是插件:nikolaydyankov.com/Dev/mosaic - 尝试使用下面的设置,看看转换是如何停止工作的。我尝试对此进行调试,记录所有变量,测试所有新间隔,但什么也没做。它只是行不通。
  • 这不是一个好主意。 The specification 不保证句柄的任何特定顺序,只保证它们是数字和唯一的。
  • 规范声明“让句柄是用户代理定义的大于零的整数,它将标识此调用设置的超时。”也就是说,积极而独特。没有其他保证。
  • 坏主意,因为@JanDvorak 指定的原因,而且它还会停止不是由您的代码创建的间隔。
  • 这是对各种难以捕获的错误的欢迎信息...最好跟踪您在数组或对象中创建的间隔,并且只清除那些.. .
【解决方案2】:

将它们存储在一个对象中。由于您是唯一制作这些间隔的人,并且您知道它们是什么,因此您可以存储它们,然后随心所欲地处理它们。我会为此专门创建一个对象,例如:

var interval = {
    // to keep a reference to all the intervals
    intervals : new Set(),
    
    // create another interval
    make(...args) {
        var newInterval = setInterval(...args);
        this.intervals.add(newInterval);
        return newInterval;
    },

    // clear a single interval
    clear(id) {
        this.intervals.delete(id);
        return clearInterval(id);
    },

    // clear all intervals
    clearAll() {
        for (var id of this.intervals) {
            this.clear(id);
        }
    }
};

你的第一个问题可能是

为什么要为此制作一个单独的对象?

Watson,这是为了让您与您的插件/项目相关的手工间隔远离窥探,这样您就不会在页面中设置与您的插件无关的其他间隔。

是的,但为什么我不能将它存储在基础对象中?

您当然可以,但我认为这种方式更清洁。它将您在基础中执行的逻辑与奇怪的超时逻辑分开。

为什么将区间存储在 Set 中而不是数组中?

访问速度更快,代码更简洁。真的,你可以去任何一种方式。

【讨论】:

  • 我使用数组作为数据结构,但无论如何,这是正确的做法。如果您不想杀死所有人,甚至可以有不同的间隔“包装器”。好答案!
【解决方案3】:

初始化定时器并将其设置为窗口对象。 Window.myInterval 将保存 Timer 的 ID。

点赞window.myInterval = setInterval(function() { console.log('hi'); }, 1000);

要清除间隔,您可以这样写

if(window.myInterval != undefined && window.myInterval != 'undefined'){
    window.clearInterval(window.myInterval);
    alert('Timer cleared with id'+window.myInterval);
}

【讨论】:

    【解决方案4】:

    当你设置一个间隔时,你会得到一个指向它的指针。 要清除所有间隔,您需要存储所有间隔:

    // Initially
    var arr = [];
    arr.push(setInterval(function () {
        console.log(1);
      }, 1000));
    arr.push(setInterval(function () {
        console.log(2);
      }, 1000));
    arr.push(setInterval(function () {
        console.log(3);
      }, 1000));
      
    

    以下循环将清除所有间隔

    // Clear multiple Intervals
      arr.map((a) => {
        console.log(a)
        clearInterval(a);
        arr = [];
      })
    

    【讨论】:

    • 如果您既不返回值也不创建另一个数组,请使用 forEach 而不是 map
    猜你喜欢
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多