Javascript setTimeout延迟 - 我尝试过但尝试过但这不会减慢

时间:2016-01-05 14:34:57

标签: javascript html

此代码应该一次更改一个五个图像。我不会详细介绍,但它需要使用数组来控制图像。问题是,图像变化之间没有延迟。我已经研究了其他人遇到的setTimeout问题,但看不出我做错了。

我知道可能有更简洁的方法可以做到这一点,但我试图通过简单的解释代码来保持它非常简单。

<html lang="en">
<head>


    <script>
        var array=[0,0,0,0,0];

        function updatelights() {
            if (array[0]==1) {
                document.images.light1.src="lighton.png";
            }
            else {
                document.images.light1.src="lightoff.png";
            }
            if (array[1]==1) {
                document.images.light2.src="lighton.png";
            }
            else {
                document.images.light2.src="lightoff.png";
            }
            //other if statements here as above
        }

        function animatelights() {
            light1on();
            setTimeout(updatelights,1000);
            light2on();
            setTimeout(updatelights,1000);
            light3on();
            setTimeout(updatelights,1000);
            light4on();
            setTimeout(updatelights,1000);
            light5on();
            setTimeout(updatelights,1000);
        }

        function light1on() {
            array=[1,0,0,0,0];
        }
        function light2on() {
            array=[0,1,0,0,0];
        }
        function light3on() {
            array=[0,0,1,0,0];
        }
        function light4on() {
            array=[0,0,0,1,0];
        }
        function light5on() {
            array=[0,0,0,0,1];
        }

    </script>

</head>

<body>

    <!-- This is an HTML table with five columns. There is an image in each column-->
    <table style="width:100%">
        <tr>
            <td><img name="light1" src="lightoff.png"></td>
            <td><img name="light2" src="lightoff.png"></td> 
            <td><img name="light3" src="lightoff.png"></td>
            <td><img name="light4" src="lightoff.png"></td>
            <td><img name="light5" src="lightoff.png"></td>
        </tr>
    </table>

    <!-- This is an HTML button -->
    <button type = "button" onclick="animatelights()"> Animate </button>

</body>
</html>

5 个答案:

答案 0 :(得分:4)

当我看到这个时:

    light1on();
    setTimeout(updatelights,1000);
    light2on();
    setTimeout(updatelights,1000);
    light3on();
    setTimeout(updatelights,1000);
    light4on();
    setTimeout(updatelights,1000);
    light5on();
    setTimeout(updatelights,1000);

看起来你希望事情逐行进行,但是代码不按顺序执行。 setTimeout是非阻塞的,意味着该代码的实际顺序为:

light1on();
light2on();
light3on();
light4on();
light5on();

然后一秒钟后,所有的updatelights都被调用:

  updatelights(); //from setTimeout
  updatelights(); //from setTimeout
  updatelights(); //from setTimeout
  updatelights(); //from setTimeout
  updatelights(); //from setTimeout

所以解决方案应该是这样的:

var arr = [light1on, light2on, light3on, light4on, light5on];
var i = 1;

arr[0]();
var si = setInterval(function(){
  if(i >= arr.length){
    clearInterval(si);
  }
  arr[i]();
  i++
  updatelights();
}, 1000);

答案 1 :(得分:1)

setTimeout不是睡眠功能。

它将传递给它的函数放入队列中,以便在以下时间调用:

  • 指定的时间已经过了
  • JS事件循环并不忙于运行另一个函数

您正在逐个调用每个lightNon函数,然后在大约一秒后调用updatelights 5次。

解决这个问题的一般方法是:

  1. 用一组函数替换你的lightNon函数(或者更好的是,使用一组数据的函数)
  2. 创建一个变量来跟踪下一个要处理的数组的索引
  3. 每秒使用setInterval运行以下功能:
    • 设置数组
    • 调用更新功能
    • 增加跟踪索引的变量

答案 2 :(得分:1)

你有很多不必要的代码。如果我试图从你的例子中学习这些东西,我会彻底搞糊涂。我冒昧地简化了你的榜样。

Here's a JS Fiddle

HTML(我为图片添加了一个类名)

<table style="width:100%">
    <tr>
        <td><img class='rotateImage' name="light1" src="http://antigonishoptical.ca/images/black-dot.png"></td>
        <td><img class='rotateImage' name="light2" src="http://antigonishoptical.ca/images/black-dot.png"></td> 
        <td><img class='rotateImage' name="light3" src="http://antigonishoptical.ca/images/black-dot.png"></td>
        <td><img class='rotateImage' name="light4" src="http://antigonishoptical.ca/images/black-dot.png"></td>
        <td><img class='rotateImage' name="light5" src="http://antigonishoptical.ca/images/black-dot.png"></td>
    </tr>
</table>

<!-- This is an HTML button -->
<button type = "button" onclick="animatelights()"> Animate </button>

和JS ..

// URL for the on light
var lightsOn = "http://info.sonicretro.org/images/1/1b/Reddot.gif";

// URL for the off light
var lightsOff = "http://antigonishoptical.ca/images/black-dot.png";

// The active light (you don't need an array since you only have one light on at a time)
var activeLight = 0;

function animatelights() {

    // Get an array of your images by adding a class name to them
    var lights = document.getElementsByClassName('rotateImage');

    // Loop thru the image and turn all the lights off
    for(var i=0; i<lights.length; i++) lights[i].src = lightsOff;

    // Then turn on the light that is currently active
    lights[activeLight].src = lightsOn;

    // increment the active light variable so the next light lights up next time
    activeLight++;

    // Check to see if we've gone through all inputs. If we have the cirrent index won't exists, 
    // so we reset it back to zero
    if('undefined' === typeof lights[activeLight]) activeLight = 0;

    // After three seconds, call the function again recursively
    setTimeout(animatelights, 3000);
}

答案 3 :(得分:0)

  

这是错误的approch。

setTimeout()不会暂停或停止执行。它会在给定时间后执行一些代码。你可以使用回调函数来阻止执行这样的事情:

 function second()
 {
   alert("ok");
 }

setTimeout(second,100);

function secondFunction() {
  alert("after 1 second");
}

setTimeout(secondFunction, 1000);

答案 4 :(得分:0)

问题是因为您正在立即更改array

您希望在延迟(light2on)后致电setTimeout(等)。正确的是在setTimeout回调函数中调用它。您必须在light[number]on之前致电updatelights。 为每个人这样做:

setTimeout(function(){light2on();updatelights()},1000)

但是间隔会更快,并且不需要创建这些函数和全局变量。