【问题标题】:Stop setInterval call in JavaScript在 JavaScript 中停止 setInterval 调用
【发布时间】:2010-09-11 15:59:06
【问题描述】:

我使用setInterval(fname, 10000); 在 JavaScript 中每 10 秒调用一次函数。是否可以在某些事件上停止调用它?

我希望用户能够停止重复刷新数据。

【问题讨论】:

    标签: javascript dom-events setinterval


    【解决方案1】:

    setInterval()返回一个区间ID,你可以把它传递给clearInterval()

    var refreshIntervalId = setInterval(fname, 10000);
    
    /* later */
    clearInterval(refreshIntervalId);
    

    请参阅 setInterval()clearInterval() 的文档。

    【讨论】:

    • 在使用 'clearInterval()' 停止后如何重新启动它?如果我尝试重新启动它,我会运行 2 倍的 setInterval。
    • 我也是每次我想使用 SetInterval(MyFunction , 4000);它变得越来越快,每次快 2 倍 :( 我如何重新启动 setinterval??
    • SetInterval() 不会改变您通过它的速度。如果每次调用 SetInterval() 时它正在做的事情都加快了速度,那么您有多个同时运行的计时器,应该提出一个新问题。
    • 确保你真的停止了它。由于范围可变,您可能没有正确的 ID 来调用 clearInterval。我使用了window.refreshIntervalId 而不是局部变量,效果很好!
    • 我已经开始将 setInterval 句柄附加到它的关联元素(如果相关):$('foo').data('interval', setInterval(fn, 100)); 然后用clearInterval($('foo').data('interval')); 清除它我确信有一个非jQuery 方法可以做到这一点,也是。
    【解决方案2】:

    如果你将setInterval的返回值设置为一个变量,你可以使用clearInterval来停止它。

    var myTimer = setInterval(...);
    clearInterval(myTimer);
    

    【讨论】:

    • 我看不出这和约翰的回答有什么区别
    • 迟到了,但是,我认为它被复制了一些单词差异,没有比约翰的回答更清楚
    【解决方案3】:

    你可以设置一个新变量,让它每次运行时递增 ++(加一),然后我使用条件语句来结束它:

    var intervalId = null;
    var varCounter = 0;
    var varName = function(){
         if(varCounter <= 10) {
              varCounter++;
              /* your code goes here */
         } else {
              clearInterval(intervalId);
         }
    };
    
    $(document).ready(function(){
         intervalId = setInterval(varName, 10000);
    });
    

    希望对你有帮助,而且是对的。

    【讨论】:

    • 我很惊讶地发现这行得通clearInterval(varName);。我希望 clearInterval 在传递函数名称时不起作用,我认为它需要间隔 ID。我想这只有在你有一个命名函数时才有效,因为你不能将匿名函数作为变量传递给它自己。
    • 其实我觉得行不通。由于计数器的限制,代码停止执行,但间隔不断触发 varName()。尝试在 clearInterval() 之后(在 else 子句中)记录任何内容,您将看到它被永远写入。
    • $(document).ready(function(){ }); 是 jQuery,这就是它不起作用的原因。至少应该提到这一点。
    • @OMGrant,除了一个不起作用的例子,你还有一个名为varName的变量,它存储了一个未命名的函数——wha??恕我直言,您应该更改或删除此答案。
    • MSN 非常清楚,clearInterval 需要一个 id 而不是函数:developer.mozilla.org/en-US/docs/Web/API/WindowTimers/…。由于此答案不正确且具有误导性,我将投票否决。
    【解决方案4】:

    上面的答案已经说明了setInterval是如何返回一个句柄的,以及这个句柄是如何用来取消Interval定时器的。

    一些架构方面的考虑:

    请不要使用“无范围”变量。最安全的方法是使用 DOM 对象的属性。最简单的地方是“文件”。如果刷新是通过启动/停止按钮启动的,您可以使用该按钮本身:

    <a onclick="start(this);">Start</a>
    
    <script>
    function start(d){
        if (d.interval){
            clearInterval(d.interval);
            d.innerHTML='Start';
        } else {
            d.interval=setInterval(function(){
              //refresh here
            },10000);
            d.innerHTML='Stop';
        }
    }
    </script>
    

    由于该函数是在按钮单击处理程序中定义的,因此您不必再次定义它。如果再次单击该按钮,则可以恢复计时器。

    【讨论】:

    • 将它放在document 上比放在window 上更好吗?
    • 更正。我的意思是document.body。在我的代码示例中,我有效地使用了按钮本身。按钮没有 ID,但“this”指针绑定到函数中的“d”参数。使用“窗口”作为范围是有风险的,因为函数也在那里。例如,“function test(){}”可以通过 window.test 访问,这与根本不使用范围相同,因为它是一种速记。希望这会有所帮助。
    • 不要丢失“无作用域”变量->不要使用“无作用域”我会编辑它,但更改少于 6 个字母,并且错误令人困惑。跨度>
    • 你不需要 DOM。只需我们一个 IIFE 即可避免全球范围污染。
    • 我必须在 innerhtml='start' 之后添加 'd.interval=undefined' 才能使其再次工作。因为这样只会工作一次。
    【解决方案5】:

    已经回答...但是如果您需要一个特色的、可重复使用的计时器,它还支持不同时间间隔的多个任务,您可以使用我的TaskTimer(适用于 Node 和浏览器)。

    // Timer with 1000ms (1 second) base interval resolution.
    const timer = new TaskTimer(1000);
    
    // Add task(s) based on tick intervals.
    timer.add({
        id: 'job1',         // unique id of the task
        tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
        totalRuns: 10,      // run 10 times only. (omit for unlimited times)
        callback(task) {
            // code to be executed on each run
            console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
            // stop the timer anytime you like
            if (someCondition()) timer.stop();
            // or simply remove this task if you have others
            if (someCondition()) timer.remove(task.id);
        }
    });
    
    // Start the timer
    timer.start();
    

    在您的情况下,当用户点击干扰数据刷新时;如果他们需要重新启用,您也可以致电 timer.pause() 然后 timer.resume()

    more here

    【讨论】:

      【解决方案6】:

      clearInterval() 方法可用于清除使用 setInterval() 方法设置的计时器。

      setInterval 总是返回一个 ID 值。可以在 clearInterval() 中传递此值以停止计时器。 这是一个从 30 开始到 0 时停止的计时器示例。

        let time = 30;
        const timeValue = setInterval((interval) => {
        time = this.time - 1;
        if (time <= 0) {
          clearInterval(timeValue);
        }
      }, 1000);
      

      【讨论】:

        【解决方案7】:

        @cnu,

        您可以停止间隔,当尝试在查看您的控制台浏览器(F12)之前运行代码时...尝试注释 clearInterval(trigger) 再次查看控制台,而不是美化器? :P

        检查示例来源:

        var trigger = setInterval(function() { 
          if (document.getElementById('sandroalvares') != null) {
            document.write('<div id="sandroalvares" style="background: yellow; width:200px;">SandroAlvares</div>');
            clearInterval(trigger);
            console.log('Success');
          } else {
            console.log('Trigger!!');
          }
        }, 1000);
        &lt;div id="sandroalvares" style="background: gold; width:200px;"&gt;Author&lt;/div&gt;

        【讨论】:

          【解决方案8】:

          这就是我使用 clearInterval() 方法在 10 秒后停止计时器的方式。

          function startCountDown() {
            var countdownNumberEl = document.getElementById('countdown-number');
            var countdown = 10;
            const interval = setInterval(() => {
              countdown = --countdown <= 0 ? 10 : countdown;
              countdownNumberEl.textContent = countdown;
              if (countdown == 1) {
                clearInterval(interval);
              }
            }, 1000)
          }
          <head>
            <body>
              <button id="countdown-number" onclick="startCountDown();">Show Time </button>
            </body>
          </head>

          【讨论】:

            【解决方案9】:

            声明变量以分配从 setInterval(...) 返回的值 并将分配的变量传递给 clearInterval();

            例如

            var timer, intervalInSec = 2;
            
            timer = setInterval(func, intervalInSec*1000, 30 ); // third parameter is argument to called function 'func'
            
            function func(param){
               console.log(param);
            }
            

            // 任何你可以访问上面声明的 timer 的地方调用 clearInterval

            $('.htmlelement').click( function(){  // any event you want
            
                   clearInterval(timer);// Stops or does the work
            });
            

            【讨论】:

              【解决方案10】:

              在 nodeJS 中,您可以在 setInterval 函数中使用“this”特殊关键字。

              您可以使用这个this关键字来清除Interval,这里是一个例子:

              setInterval(
                  function clear() {
                          clearInterval(this) 
                     return clear;
                  }()
              , 1000)
              

              当您在函数中打印 this 特殊关键字的值时,您会输出一个 Timeout 对象 Timeout {...}

              【讨论】:

                【解决方案11】:

                clearInterval()

                请注意,您可以使用此功能启动和暂停您的代码。这个名字有点欺骗性,因为它说的是 CLEAR,但它并没有清除任何东西。它实际上暂停了。

                使用此代码进行测试:

                HTML:

                <div id='count'>100</div>
                <button id='start' onclick='start()'>Start</button>
                <button id='stop' onclick='stop()'>Stop</button>
                

                JavaScript:

                let count;
                
                function start(){
                 count = setInterval(timer,100)  /// HERE WE RUN setInterval()
                }
                
                function timer(){
                  document.getElementById('count').innerText--;
                }
                
                
                function stop(){
                  clearInterval(count)   /// here we PAUSE  setInterval()  with clearInterval() code
                }

                【讨论】:

                  【解决方案12】:

                  使用 setTimeOut 在一段时间后停止间隔。

                  var interVal = setInterval(function(){console.log("Running")  }, 1000);
                   setTimeout(function (argument) {
                      clearInterval(interVal);
                   },10000);
                  

                  【讨论】:

                    【解决方案13】:

                    很多人都给出了很好的答案,clearInterval 是正确的解决方案。

                    但我认为我们可以做得更多,让我们的编辑器使用 javascript 计时器强制执行最佳实践。

                    忘记清除setTimeoutsetInterval设置的定时器总是很容易,这可能会导致难以发现的错误。

                    所以我为上面的问题创建了一个 eslint 插件。

                    https://github.com/littlee/eslint-plugin-clean-timer

                    【讨论】:

                      【解决方案14】:

                      我想下面的代码会有所帮助:

                      var refreshIntervalId = setInterval(fname, 10000);
                      
                      clearInterval(refreshIntervalId);
                      

                      您的代码 100% 正确... 那么... 有什么问题?或者它是一个教程......

                      【讨论】:

                        【解决方案15】:

                        试试

                        let refresch = ()=>  document.body.style= 'background: #'
                          +Math.random().toString(16).slice(-6);
                        
                        let intId = setInterval(refresch, 1000);
                        
                        let stop = ()=> clearInterval(intId);
                        body {transition: 1s}
                        &lt;button onclick="stop()"&gt;Stop&lt;/button&gt;

                        【讨论】:

                          【解决方案16】:

                          为什么不使用更简单的方法呢?添加课程!

                          只需添加一个告诉间隔不要做任何事情的类。例如:悬停时。

                          var i = 0;
                          this.setInterval(function() {
                            if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
                              console.log('Counting...');
                              $('#counter').html(i++); //just for explaining and showing
                            } else {
                              console.log('Stopped counting');
                            }
                          }, 500);
                          
                          /* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
                          $('#counter').hover(function() { //mouse enter
                              $(this).addClass('pauseInterval');
                            },function() { //mouse leave
                              $(this).removeClass('pauseInterval');
                            }
                          );
                          
                          /* Other example */
                          $('#pauseInterval').click(function() {
                            $('#counter').toggleClass('pauseInterval');
                          });
                          body {
                            background-color: #eee;
                            font-family: Calibri, Arial, sans-serif;
                          }
                          #counter {
                            width: 50%;
                            background: #ddd;
                            border: 2px solid #009afd;
                            border-radius: 5px;
                            padding: 5px;
                            text-align: center;
                            transition: .3s;
                            margin: 0 auto;
                          }
                          #counter.pauseInterval {
                            border-color: red;  
                          }
                          <!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
                          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                          
                          
                          <p id="counter">&nbsp;</p>
                          <button id="pauseInterval">Pause</button></p>

                          多年来,我一直在寻找这种快速简便的方法,因此我发布了几个版本,以向尽可能多的人介绍它。

                          【讨论】:

                          • 对我来说似乎并不简单......我也认为删除间隔而不是保持对无操作函数的调用更干净。
                          • 我不同意。 this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500); 是您所拥有的所有代码。此外,检查是您要做的第一件事,因此在悬停时它非常轻巧。这就是它的用途:暂时暂停功能。如果你想无限期地终止它:当然你删除间隔。
                          • 这相当于轮询,通常不鼓励使用。它会将 CPU 从低功耗状态唤醒,只是为了进行(可能)无用的检查。在本例中,它还将反馈从立即延迟到 0 到 500 毫秒。
                          • 我完全不同意你的观点,即使我在 2 年前编写了代码。无论如何,柜台必须在那里,因为 OP 要求它。当然,如果您在按下按钮后使用它来停止计数器,例如,这将是一个次优解决方案,但只是在悬停时暂停,这是可用的最简单的解决方案之一。
                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2014-09-05
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多