我正在制作一个西蒙游戏,我试图按下按钮的时间间隔为1秒。但似乎我的setTimeout函数没有完成它的工作,所有点击都是在没有1s间隔的情况下立即执行的。我尝试在循环外提醒一些东西,它运行得很好。任何人都可以帮我这个吗?
这是我的JavaScript代码:
for (var count = 1; count <= 20; count++) {
$("#count").html(count);
seq.push(Math.floor(Math.random() * 4));
seq.forEach(function(press) {
setTimeout(function() {
eval('$("#button' + press + '").click();');
}, 1000);
});
}
和相应的html:
<p>count: <span id="count">0</span></p>
<button id="button0" onclick="sound1.play()"></button>
<button id="button1" onclick="sound2.play()"></button>
<button id="button2" onclick="sound3.play()"></button>
<button id="button3" onclick="sound4.play()"></button>
谢谢!
答案 0 :(得分:1)
The problem is the way you do setTimeout
.
The for loop iterates within a few milliseconds and you basically request all the clicks to run one second later, so they all happen one second later but at the same time.
If you request the first click after one, the second click after two seconds and so forth, you'll get what you want:
seq.forEach(function(press, i) {
setTimeout(function() {
$("#button" + press).click();
}, 1000 * i);
});
Also note that you probably want to restructure your code to not do this twenty times over:
for (var count = 1; count <= 20; count++) {
$("#count").html(count);
seq.push(Math.floor(Math.random() * 4));
}
seq.forEach(function(press, i) {
setTimeout(function() {
$("#button" + press).click();
}, 1000 * i);
});
答案 1 :(得分:0)
您的eval功能在1秒后运行,但所有功能都是。
会发生什么:
loop from 1 to 20
add an item to the seq array
loop through the seq array
define the setTimeout to happen in 1 second.
在执行setTimeout的过程中,您的代码不会休眠。因此,所有这些都在循环中定义,尽可能接近所请求的1秒。
答案 2 :(得分:0)
您可以通过在setTimeout
内重复调用函数来进行异步循环:这样排序和延迟将按照需要进行。
这是一个包含其他一些想法的工作片段:
// First generate the array (only 8 to not annoy SO public):
var seq = Array.from(Array(8), _ => Math.floor(Math.random() * 4));
function replay() {
// Iterate seq asynchronously
(function loop(i) {
if (i >= seq.length) return; // all done
$("#count").text(i+1);
$("#buttons>button").eq(seq[i]).click();
setTimeout(loop.bind(null, i+1), 1000);
})(0);
}
$("#buttons>button").click(function () {
// Play sound here...
playNote([523, 659, 784, 880][$(this).index()], 800);
// Some visual effect:
$(this).addClass("clicked");
setTimeout($(this).removeClass.bind($(this), "clicked"), 800);
});
// Sound support
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playNote(frequency, duration) {
// create Oscillator node
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = frequency; // value in hertz
oscillator.connect(audioCtx.destination);
oscillator.start();
setTimeout(oscillator.stop.bind(oscillator), duration);
}
// Play the sequence on page load
replay();
button {
border: 2px solid silver;
}
button.clicked {
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>count (up to 8): <span id="count">0</span></p>
<div id="buttons">
<button>A</button>
<button>B</button>
<button>C</button>
<button>D</button>
</div>