通过settimeout迭代某些函数不能像我预期的那样工作

时间:2015-12-29 18:27:32

标签: javascript

我正在玩javascript并试图通过一些在数组中定义的颜色进行迭代,以确保我正确输入颜色名称。我使用了以下代码:

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

我很惊讶页面加载速度非常快,只是在后台显示“黄色”。我以为使用setTimeout要求延迟2秒。如果我通过控制台看,我会看到有关颜色设置的消息;但他们没有延迟2秒。我是否误解了settimeout()是如何工作的,或者这与我使用onload事件有什么关系?

2 个答案:

答案 0 :(得分:2)

设置超时需要函数引用。您只需立即调用该功能即可。用这样的匿名函数包装它:

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

另外,因为我喜欢它 - 你可以使用ES6 lambda语法缩短你的show_colors方法。

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

答案 1 :(得分:0)

有几点。

  1. 传递setTimeout一个要执行的函数,如前所述。
  2. 该函数需要显示下一个颜色,而不是使用循环计数器的最后一个值。一种方法是将颜色保持在功能范围内。
  3. 设置所有定时器调用需要将颜色分开。目前它们都在两秒后执行。您可能只会看到最后一种颜色。
  4. E.G。

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