我正在用我正在网页上的JavaScript制作记忆游戏。我有3个分别标记为1、2和3的按钮,它们应该按一定顺序先变绿再变白。顺序是随机的,每转增加1。然后应该假定播放器以正确的顺序单击按钮。问题是,当我将按钮的颜色更改为绿色时,而不是每个按钮都以正确的顺序先变绿再变白,而是一次变绿。这是JavaScript逻辑:
function lightUp() {
var arrayOrder = gameOrder.split("");
for(let i = 0; i < arrayOrder.length; i++) {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "green";
setTimeout(function() {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "white";
}, 1000);
}
}
[gameOrder是数字顺序的字符串(例如“ 12331232123”)
我认为游戏由于setTimeout的工作方式而无法正常工作,我相信它会在后台暂停,并允许for循环继续运行,而不是暂停整个过程一秒钟(这就是我正在尝试的方法要做)。
我希望每个按钮先打开然后关闭,然后再下一个按钮更改颜色。因此,如果顺序是1 2 3,我希望按钮1变成绿色,然后白色,然后按钮2变成绿色,然后白色,最后让按钮3变成绿色,然后白色。
正如espacarello指出的那样,JS不是同步的。您可以使函数异步并等待setTimeout
。
这是我使用JS“动画化”事物的首选方式:
async function lightUp() {
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
for (const i of gameOrder.split('')) {
const el = document.getElementById(`but${i}`);
el.style.backgroundColor = 'green';
await sleep(1000);
el.style.backgroundColor = 'white';
}
}
这保持简单优雅,而不会因大量回调,递归或嵌套setTimeout
而使您的代码混乱。它只是一个功能。
Edit:重要的是要注意IE不支持Promises或Arrow Function语法。请参阅其他两个答案以获得更广泛的支持。
您的代码存在的问题是for循环可以立即运行,而不会延迟。您在编写代码时认为间隔会导致循环等待执行。问题是,它会立即运行而无需等待。
使用队列类型的系统在其中运行步骤,完成后将运行下一个,直到您用尽所有要做的事情。
var steps = [1,2,3,2,1,3,1]
var delay = 1000
var step = 0
function next () {
var button = document.getElementById('btn' + steps[step])
button.classList.add("on")
window.setTimeout( function () {
button.classList.remove("on")
step++
if(step<steps.length) next()
}, delay)
}
next()
.on {
background-color: green;
}
<button id="btn1">One</button>
<button id="btn2">Two</button>
<button id="btn3">Three</button>
您可以按照以下步骤做...
function lightUp() {
var arrayOrder = gameOrder.split("");
for (let i = 0; i < arrayOrder.length; i++) {
(function(i) {
setTimeout(function() {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "green";
}, 1000 * i - 1000);
setTimeout(function() {
document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "white";
}, 1000 * i); // schedules excution increasingly for each iteration
})(i);
}
}
要了解有关其工作原理的更多信息,请参阅this answer