Javascript 不会更改递归函数内部的 CSS,直到递归结束



我试图创建一个页面,其中背景循环遍历每个十六进制值(从#000000到 #FFFFFF(。这是我正在使用的JS函数:

function Colours(count)
        {   
            count +=1;
            if (count > 16777215)
            {
                count = 0;
            }                   
            hex = count.toString(16);
            while (hex.length < 6)
            {
                hex = "0" + hex;
            }
            hex = "#" + hex;
            document.body.style.background = hex;
            window.setTimeout(Colours(count),10);   
        }

当单击按钮并给出参数 -1 时调用它(因此第一个十六进制值是 #000000(。

经过一些诊断,似乎它只会在递归结束后改变颜色(在这种情况下,我假设一旦它达到 #006446 的堆栈限制(。此函数将在将背景颜色更改为它达到的最终十六进制代码之前进行短暂处理。我怎样才能让它每次进入函数时都改变颜色,而不是在最后完成堆栈。

您正在将调用 Colours 函数的结果传递给 setTimeout。您应该传递对该函数的引用,并使用 setTimeout 的第三个参数传递参数。

window.setTimeout(Colours, 10, count + 1);

function Colours(count) {
  if (count > 16777215) {
    count = 0;
  }
  hex = count.toString(16);
  while (hex.length < 6) {
    hex = "0" + hex;
  }
  hex = "#" + hex;
  document.body.style.background = hex;
  window.setTimeout(Colours, 10, count + 1);
}
Colours(0)

这不会做你认为它做的事情:

window.setTimeout(Colours(count),10)

这是立即执行Colours(count)并为该函数的返回值设置超时。 由于函数执行之间没有超时,因此整个事情都是阻塞的,并且在阻塞代码完成之前不会更新 DOM。

您希望传递函数本身,而不是函数的执行。 在这种情况下,它可能是这样的:

window.setTimeout(function () { Colours(count); }, 10)

这会将调用包装在不立即执行的函数中。 然后,函数将在超时期间执行。

Javascript有时会变得喜怒无常。您的问题主要基于您的代码没有正确的延迟这一事实,因此浏览器通过仅显示上次迭代来优化。下面的代码将使用 setTimeout 解决此问题。请参阅下面的 JSFiddle 链接。

function Colours(count) {
  if (count > 16777215) {
    count = 0;
    }
  hex = count.toString(16);
  while (hex.length < 6) {
    hex = "0" + hex;
  }
  hex = "#" + hex;
  document.body.style.background = hex;
  window.setTimeout(Colours, 10, count + 1);
}
Colours(0)

https://jsfiddle.net/y68sfptp/1/

编辑:对不起,刚刚看到了之前的答案。

最新更新