2015-06-09 71 views
4

我想动态更改setInterval的区间值。由于在setInterval回调函数中存在一个循环,我很挣扎。我看到了很多关于stackoverflow的问题。但是没有任何解决方案可以帮助我。如果有人知道答案,请用一个例子来解释。谢谢。 这是我的代码。动态更改setInterval值

<html> 
<head> 
    <script type="text/javascript"> 
     var speed = 10; 
     function updateSlider(slideAmount) { 
      speed = slideAmount; 
     } 
     function load() { 
      downloadUrl("points.xml", function (data) { 
       /* code */ 
       abc(); 
      }); 
      function abc() { 
       function track() { 
        /* code */ 
        downloadUrl("points.xml", function (data) { 
         var xml = data.responseXML; 
         var points = xml.documentElement.getElementsByTagName("point"); 
         var i = 0; 
         setInterval(function() { 
          if (i != points.length) { 
           alert(speed); 
          } 
          i++; 
         }, 100 * speed); 
        }); 
       } 
       track(); 
      } 
     } 
     function downloadUrl(url, callback) { 
      var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest; 
      request.onreadystatechange = function() { 
       if (request.readyState == 4) { 
        request.onreadystatechange = doNothing; 
        callback(request, request.status); 
       } 
      }; 
      request.open('GET', url, true); 
      request.setRequestHeader("Content-type", "text/xml"); 
      request.send(null); 
     } 
     function doNothing() { 
     } 
    </script> 
</head> 
<body onload="load();"> 
    <div id="slider"> 
     5% <input id="slide" type="range" min="1" max="20" step="5" value="10" onchange="updateSlider(this.value)" /> 200% 
    </div> 
    <div id="chosen">10</div> 
</body> 

+0

一次的间隔设置,它不能改变,但可以通过'clearInterval'停止并重置。为了您的需要,使用'setTimeout'并重复使用更改的超时值重新进行设置。 – marekful

+0

你可能想看看[这个答案](http://stackoverflow.com/a/19801315/1465828) – Aprian

回答

7

诀窍是不使用setInterval,并在循环中使用setTimeout代替。

setInterval读取您给它的计时值一次,基于此计时的计划表并忘记它。如果您已将间隔分配给像myInterval这样的变量,则唯一可以执行的操作是clearInterval(myInterval)

setTimeout大致相同,除了我们可以使用它来手动循环相同的功能。手动循环允许我们在每次超时后更改setTimeout的时间。

下面是一个简单的例子。将滑块移动到左侧会使滴答声更快,而向右移动会更慢。

DEMO

var timing = 250, 
 
    i = 0, 
 
    output = document.getElementById('output'); 
 

 
function loop() { 
 
    i++; 
 
    output.innerHTML = i; 
 
    window.setTimeout(loop, timing); 
 
} 
 

 
document.querySelector('input[type="range"]').addEventListener('change', function (e) { 
 
    timing = parseInt(this.value); 
 
}); 
 

 
loop();
<input type="range" min="100" max="500" value="250" /> 
 
<div id="output"></div>

作为一个方面说明:使用此模式是几乎总是比使用setInterval一个更好的选择。 setInterval运行的机会,您的功能执行可能需要比时间间隔的持续时间更长。如果您在函数中最后调用setTimeout,则这种情况在循环setTimeout时不会发生。

文档:

+0

这很好用,非常感谢你。 –

0

这是没有的setInterval版本我总是用:

function timer() 
{ 
    var timer = { 
     running: false, 
     iv: 5000, 
     timeout: false, 
     cb : function(){}, 
     start : function(cb,iv,sd){ 
      var elm = this; 
      clearInterval(this.timeout); 
      this.running = true; 
      if(cb) this.cb = cb; 
      if(iv) this.iv = iv; 
      if(sd) elm.execute(elm); 
      this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv); 
     }, 
     execute : function(e){ 
      if(!e.running) return false; 
      e.cb(); 
      e.start(); 
     }, 
     stop : function(){ 
      this.running = false; 
     }, 
     set_interval : function(iv){ 
      clearInterval(this.timeout); 
      this.start(false, iv); 
     } 
    }; 
    return timer; 
} 

用法:

var timer_1 = new timer(); 
timer_1.start(function(){ 
    //magic here 
}, 2000, false); 

var timer_2 = new timer(); 
timer_2.start(function(){ 
    //more magic here 
}, 3000, true); 

//change the interval 
timer_2.set_interval(4000); 

//stop the timer 
timer_1.stop(); 

启动功能的最后一个参数是一个布尔值,如果函数需要在0

来运行你也可以在这里找到脚本:https://github.com/Atticweb/smart-interval