【问题标题】:How to clear a javascript timeout thats set within a function如何清除在函数中设置的 javascript 超时
【发布时间】:2012-01-06 08:06:39
【问题描述】:

我在 Javascript 中有一个递归类型函数,运行如下:

function loadThumb(thumb) {
    rotate=setTimeout(function() {
        loadThumb(next);
    }, delay);
}

注意:我已经简化了函数以使其更易于阅读。

我有这样的“a”标签

<a href="#" onclick="loadThumb(3); clearTimeout(rotate);">Load thumb 3</a>

但是,它们不会清除计时器,计时器会继续循环通过函数,而不管 clearTimeout() 是否被调用。

任何想法为什么?我认为这可能与范围问题或类似问题有关。

【问题讨论】:

    标签: javascript settimeout


    【解决方案1】:

    是的,您需要将 rotate 设为全局变量。只需像这样在函数外部声明它:

    var rotate;
    var delay = 1000;
    
    function loadThumb(thumb) {
        alert("loading thumb: " + thumb);
        rotate = setTimeout(function() {
            loadThumb(thumb + 1);
        }, delay);
    }
    

    此外,您需要确保在调用loadThumb 之前清除超时。否则,您将清除刚刚启动的计时器。

    <a href="#" onclick="clearTimeout(rotate); loadThumb(3);">Load thumb 3</a>
    

    小提琴:http://jsfiddle.net/63FUD/

    【讨论】:

    • 并返回 false。并且没有 var rotate 应该使它成为一个 windows 范围的 var
    • 哦,是的,这就是我正在做的事情,在事情变得混乱之后调用它,它现在正在工作。谢谢。
    【解决方案2】:

    可能是范围问题,所以作为全局变量旋转并调用clearTimeout(rotate);

    参考clearTimeout() example

    【讨论】:

      【解决方案3】:

      如果您没有在外部声明 rotate,这可能是一个范围界定问题。

      试试这个:

      var rotate = 0;
      function loadThumb(thumb) {
      
          rotate=setTimeout(function() {
              loadThumb(next);
          }, delay);
      
      }
      

      【讨论】:

        【解决方案4】:

        在链接上返回 false

        由于您没有使用 var rotate,它不应该是范围问题,因为 rotate 将在窗口范围内。你能显示完整的代码吗?

        内联脚本被认为是糟糕的编码 - 你应该附加页面的事件处理程序

        另外,您不应该在可能为一张图像调用的函数中设置 setTimeout

        试试这个:

        var rotate,next=1;
        function loadThumb(thumb) {
          if (thumb) ... use thumb
          else ... use next
        }
        
        function slide() {
            rotate=setInterval(function() {
                loadThumb();
                next++; 
                if (next>=images.length) next=0;
            }, delay);
        }
        
        window.onload=function() {
          var links = document.getElementsByTagName("a");
          if (links[i].className==="thumbLink") {
            links[i].onclick=function() {
              var idx = this.id.replace("link","");
              loadThumb(idx);
              clearInterval(rotate);
              return false;
            }
          }
          document.getElementById("start").onclick=function() {
            slide();
            return false;
          }
          document.getElementById("stop").onclick=function() {
            clearInterval(rotate);
            return false;
          }
          slide();
        }
        

        假设

        <a href="#" id="start">Start</a>
        <a href="#" id="stop">Stop</a>
        
        <a href="#" id="link0" class="thumbLink">Show 1</a>
        <a href="#" id="link1" class="thumbLink">Show 2</a>
        <a href="#" id="link2" class="thumbLink">Show 3</a>
        

        【讨论】:

          【解决方案5】:

          如果您必须管理多个超时,您可以使用全局范围内的对象和一些自定义方法来创建和删除您的超时。要访问这些方法,您可以将调用放在链接的 onclick 处理程序中(如示例中所示),或使用 jQuery 之类的库来绑定它们。

          <script type="text/javascript">
              var timeouts = timeouts || {};
          
              function createTimeout(name, milliseconds, callback) {
                  timeouts.name = setTimeout(callback, milliseconds);
              }
          
              function removeTimeout(name) {
                  if (typeof(timeouts.name) !== undefined) {
                      clearTimeout(timeouts.name);
                      timeouts.name = undefined;
                  }
              }
          
              createTimeout('foo', 5000, function() {
                  alert('timeout')
              });
          </script>
          

          我还在 jsFiddle 上发布了一个示例 http://jsfiddle.net/AGpzs/

          【讨论】:

            【解决方案6】:

            我不确定你到底在做什么,因为据我所知你没有发布所有代码,但这对我来说看起来更好:

            function loadThumb(thumb) {
            
                return setTimeout(function() {
                    loadThumb(next);
                }, delay);
            
            }
            

            然后:

            <a href="#" onclick="clearTimeout(loadThumb(3));">Load thumb 3</a>
            

            【讨论】:

            • 为什么有 javascript: - 它是默认的 - 为什么没有在函数中返回 false?
            • 虽然label javascript: 在那里没有错,但它也没有用。你也可以写foo:bar:sfgasdga:。请删除它,因为它可能会让人们认为它是必需的。 @mplungjan:我不会说它是 default。在链接(URL)中,它被用作一种协议,以便浏览器知道该做什么,但on* 属性总是被解释为 JavaScript(也许这就是你的意思,在这种情况下,nvm ;))。
            • 在我看来它不是一个标签,它是(曾经)告诉浏览器即将到来的代码是 javascript。仅当浏览器是 IE 并且页面上的 FIRST 脚本是 VBScript 时才有用,因为(至少它曾经如此)会将内联事件处理程序中的默认语言设置为 VBScript。
            • 感谢您的留言。这是我的错。通常我会放置 javascript: 当我在 href 属性中添加一些东西时。
            猜你喜欢
            • 2020-04-30
            • 2015-07-04
            • 1970-01-01
            • 2018-09-21
            • 2023-03-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-10
            相关资源
            最近更新 更多