简体   繁体   English

通过settimeout遍历某些功能无法正常工作

[英]Iterate thru some function with settimeout doesn't work as I expected

I was playing with javascript and tried to iterate thru some colors that were defined in an array just to make sure that I typed the color name correctly. 我在玩javascript,并尝试遍历数组中定义的一些颜色,以确保我正确键入了颜色名称。 I used the following code: 我使用以下代码:

<body onload="show_colors()">
  <script>
     var colors = ["blue", "cyan", "bisque", "gray", "green", "magenta", "orange", "red", "aqua", "yellow", "azure", "cadetblue", "plum"].sort();
    var myBody = document.getElementsByTagName("body")[0];

   function show_colors() {
     for (var i=0; i<colors.length; i++) {
         setTimeout(setBackgroundColor(colors[i]), 2000)
     }
   }

  function setBackgroundColor(color) {
    console.log('setting color to ' + color);
    myBody.style.background=color;
  }

</script>

I was surprised that the page loaded up pretty quickly, and just show "yellow" in the background. 我很惊讶页面加载非常快,只在后台显示“黄色”。 I thought asked to have a 2 seconds delay using the setTimeout. 我以为要求使用setTimeout延迟2秒。 If I looked thru the console, I see the messages about the colors being set; 如果通过控制台查看,则会看到有关所设置的颜色的消息。 but they weren't in a 2 seconds delay. 但是他们并没有延迟2秒。 Did I misunderstand how settimeout() work or is this have something to do with my using the onload event? 我是否误解了settimeout()的工作方式,或者这与使用onload事件有关?

Set timeout requires a function reference. 设置超时需要功能参考。 You're simply immediately invoking the function. 您只需立即调用该函数。 Wrap it in an anonymous function like this: 将其包装在一个匿名函数中,如下所示:

for (var i=0; i<colors.length; i++) {
    setTimeout(function() { 
        setBackgroundColor(colors[i])
    }, 2000)
}

Also, because I love it - you can shorten your show_colors method using ES6 lambda syntax. 另外,因为我喜欢它-您可以使用ES6 lambda语法缩短show_colors方法。

function show_colors() {
    colors.forEach(color => setTimeout(() => setBackgroundColor(color), 2000));
}

A couple of points. 有两点。

  1. pass setTimeout a function to execute, as already mentioned. 如前所述,将setTimeout传递给要执行的函数。
  2. The function needs to display the next color and not use the last value of a loop counter. 该功能需要显示下一个颜色,而不要使用循环计数器的最后一个值。 One way of doing this is to hold the color in function scope. 一种方法是将颜色保留在功能范围内。
  3. Setting up all the timer calls needs to space the colors apart. 设置所有计时器调用需要将颜色分开。 At the moment they all execute after two seconds. 目前,它们都在两秒钟后执行。 You'll probably only see the last color. 您可能只会看到最后一种颜色。

EG 例如

<script>
var colors = ["blue", "cyan", "bisque", "gray", "green", "magenta", "orange", "red", "aqua", "yellow", "azure", "cadetblue", "plum"].sort();

function toSetBackground(color) { // 1. return value is a function
    return function() {           // 2. color to use is in function scope
        console.log('setting color to ' + color);
        document.body.style.background = color;
    };
}


function show_colors() {
    for (var i=0; i<colors.  length; i++) {
        setTimeout(toSetBackground(colors[i]), 2000 * i); // 3. space the callbacks
    }
}

window.addEventListener("load", show_colors);
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM