这里需要帮助。因此,我想循环播放一系列声音,以便在延迟1000毫秒后播放。我该如何实现?我试过了,但它同时运行了所有声音:
我要使用Vanilla JS构建的Simon游戏应用程序的链接:https://codesandbox.io/s/simongame-fcc-4thbk
colorArray.forEach(color => {
setTimeout(() => {
color.play();
}, 1000)
});
答案 0 :(得分:1)
由于您已经在数组上进行迭代,因此可以在每次迭代中使用每个项目的索引。您可以使用它来为每个迭代步骤计算更高的超时。请注意,这可能会导致重叠的声音播放(假设声音的持续时间为1s),因为setTimeout
方法仅保证您指定的最小延迟。它不能保证您的代码何时能正确运行。
colorArray.forEach((color, index) => {
setTimeout(() => {
color.play();
}, 1000*++index)
});
答案 1 :(得分:1)
您可以为声音之间的延迟设置一个不断增加的增量,这将使播放声音间隔1000ms:
colorArray.forEach((color, index) => {
setTimeout(() => {
color.play();
}, 1000 * (index + 1))
// ^^^^^^^^^ delay more for each following element
});
但是,如果每种声音都大于基本延迟,则可能会遇到问题。因此,如果您有一个2秒钟的声音片段,它将播放并播放一半,则下一个片段也会播放。因此,您可能要等待第一个完成 并等待1000ms,然后再播放下一个。如果您使用的是HTMLMediaElement
,则可以收听ended
event,并在完成时播放下一个:
//set the event listeners
colorArray
.reduce((lastColor, currentColor) => {
lastColor.addEventListener("ended", () => {
setTimeout(() => {
currentColor.play();
}, 1000)
})
return currentColor;
});
//run the first playback which will then run the next one
colorArray[0].play()
一个较小的变化是使用.reduceRight
向后迭代事件。您可以这样做:
//set the event listeners
colorArray
.reduceRight((lastColor, currentColor) => {
currentColor.addEventListener("ended", () => { // <------------
setTimeout(() => { // current and last are swapped here |
lastColor.play(); //<--------------------------------------
}, 1000)
})
return currentColor;
})
.play(); //run the first playback which will then run the next one
function playAll() {
let soundsArray = [...document.querySelectorAll("audio")];
soundsArray.forEach((sound, index) => {
setTimeout(() => {
console.log("waiting for 1 second before playing");
sound.play();
}, 1000 * (index + 1));
});
}
document.querySelector("button").addEventListener("click", playAll)
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_shoot.wav" controls="controls"></audio>
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/explosion_02.wav" controls="controls"></audio>
<audio src="http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg" controls="controls"></audio>
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/explosion%2001.wav" controls="controls"></audio>
<br/>
<button>Play All</button>
这是两者的区别-使用第一种方法,特别是第三个声音片段将与第四个声音片段重叠,而第二个声音片段则不会重叠:
function playAll() {
let soundsArray = [...document.querySelectorAll("audio")];
soundsArray
.reduceRight((lastSound, currentSound) => {
currentSound.addEventListener("ended", () => {
console.log("waiting for 1 second after playing");
setTimeout(() => {
lastSound.play();
}, 1000)
});
return currentSound;
})
.play()
}
document.querySelector("button").addEventListener("click", playAll)
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/alien_shoot.wav" controls="controls"></audio>
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/explosion_02.wav" controls="controls"></audio>
<audio src="http://commondatastorage.googleapis.com/codeskulptor-demos/pyman_assets/intromusic.ogg" controls="controls"></audio>
<audio src="http://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/explosion%2001.wav" controls="controls"></audio>
<br/>
<button>Play All</button>
我使用了here的声音
答案 2 :(得分:0)
var counter = 1;
colorArray.forEach(color => { setTimeout(() => { color.play(); },counter++*1000) });
这会使colorArray
中每个元素的延迟增加1000。
答案 3 :(得分:0)
有一些选择。一种是提前安排所有声音。
colorArray.forEach((color, i) => {
setTimeout(() => {
color.play();
}, 1000 * (i + 1))
});
另一种方法是使用setInterval()
。从理论上讲,这将导致更一致的时间安排。
let index = 0;
const intervalId = setInterval(() => {
if (index < colorArray.length)
colorArray[index++].play();
else
clearInterval(intervalId)
}, 1000)
setInterval()
以指定的时间间隔调用回调。这是javascript运行时的内置方法,可以按一定的速度执行工作。
注意:javascript标准不保证在这两种方法中的任何一种定时都将是准确的,但是setInterval
的性能应更高,因为它仅在运行时调度一次回调。