动态更改setInterval值

Change setInterval value dynamically

本文关键字:setInterval 动态      更新时间:2023-09-26

我想动态地改变setInterval的间隔值。由于setInterval回调函数中存在循环,我正在挣扎。我在stackoverflow上看到了太多的问题。但是没有任何解决办法可以帮助我。如果有人知道答案,请举例说明。谢谢你!这是我的代码。

<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>

技巧是不使用setInterval,而在循环中使用setTimeout

setInterval读取你给它的定时值一次,根据这个定时调度,然后忘记它。如果您将区间分配给myInterval这样的变量,那么您唯一可以做的就是clearInterval(myInterval)

setTimeout基本相同,除了我们可以使用它手动循环相同的函数。手动循环允许我们在每次超时后更改setTimeout的计时。

这里有一个简单的例子。将滑块向左移动会使滴答变快,向右移动会使滴答变慢。

演示

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不会发生这种情况。

文档:

  • WindowTimers.setInterval
  • WindowTimers.setTimeout

这是一个没有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();

如果start函数需要在0处运行,则该函数的最后一个参数为布尔值。

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

这是另一种动态更新间隔的简单方法。

var intv_sec = 1500; // Initial interval in milliseconds
var speed = 1.5; // Multiplier
function chk_fn(){
  // Your code here
  console.log(intv_sec);
  
  
  // Reset and update interval
  clearInterval(chkh);
  intv_sec = intv_sec*speed;
  chkh = setInterval(chk_fn, intv_sec);
}
var chkh = setInterval(chk_fn, intv_sec);