当我暂停音频并将其设置为当前时间时,它会执行一些奇怪的操作。当我按下控制音频
.paused
状态的按钮时,它似乎会自动再次单击,从而阻止音频播放。为什么?
此外,如果我再次设置 currentTime,它会决定停止单击播放按钮两次。每次我设置 currentTime 时都会发生这种情况。可以用这段代码来演示。 (音频变慢只是因为示例音频太短)。
<!doctype html><html><body>
<button id="play" disabled>play</button>
<button id="idk">load audio</button>
<script>
var clicks = 0; console.clear();
idk = document.getElementById("idk");
idk.addEventListener("click", async ()=>{
aud = new Audio("https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3")
aud.addEventListener('canplaythrough', init);
}, {once: true});
function init(){
/**/aud.playbackRate = 0.25;//only to lengthen the audio to give you time.
playButton = document.getElementById("play");
playButton.disabled = false;
idk.innerText = "pause and set time to 1";
playButton.addEventListener("click", e=>{
if(aud.paused){
aud.play();
playButton.innerText = "pause";
}else{
aud.pause();
playButton.innerText = "play";
}
//Nothing different between duplicate click events, logging it takes up space
console.log(clicks++, aud.paused, /*e*/);//clicks++ to tell apart logs.
});
idk.addEventListener("click", e=>{
console.log("Rightmost element clicked");
if(!aud.paused){ aud.pause(); playButton.innerText = "play"; }
aud.currentTime = 1;
});
}
</script>
</body></html>
查看实例(由于控制台污染而删除了事件日志记录)
只需单击
load audio
,然后在获得许可后单击 play
,最后单击 pause and set time to 1
。
此后,每次实际点击都会触发点击事件两次(如日志中所示),从而阻止音频播放。解决此问题的唯一方法是再次单击
pause and set time to 1
,然后尝试单击 play
。你会成功,但如果你再次点击右键,你将再次面临这个问题。
我还注意到,稍微修改一下,双击就会变成四击,仍然会导致问题,因为四次点击是偶数。
<!doctype html><html><body>
<button id="play">play</button>
Control+Click to pause the audio and change it's currentTime value
<script>
var clicks = 0; console.clear();
playButton = document.getElementById("play");
playButton.addEventListener("click", async ()=>{
/**/window.aud = new Audio("https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3");
aud.addEventListener('canplaythrough', ()=>{
playButton.style.color = "#080";
/**/aud.playbackRate = 0.25;//only to lengthen the audio to give you time.
playButton.addEventListener("click", e=>{
if(e.ctrlKey){
if(!aud.paused){ aud.pause(); playButton.innerText = "play"; }
aud.currentTime = 1;
return;
}
if(aud.paused){
aud.play();
playButton.innerText = "pause";
}else{
aud.pause();
playButton.innerText = "play";
}
//Nothing different between duplicate click events, logging it takes up space
console.log(clicks++, aud.paused, /*e*/);//clicks++ to tell apart logs.
});
});
}, {once: true});
</script>
</body></html>
查看实例(由于控制台污染而删除了事件日志记录)
要使用第二个示例,请使用 CTRL+Click 作为
pause and set time to 1
按钮。
在这两个示例中,在控制台中运行
aud.play();
似乎可以工作,但仍然不允许播放/暂停按钮起作用并双击它们。在控制台中设置 aud.currentTime
(设置偶数次后)没有效果,连续两次设置代码 aud.currentTime
也没有效果。用户必须单击它,然后再次单击它。
这种情况发生在 ChromeOS 上的 Chrome Beta 127.0.6533.94 以及 Android 14 上的 Chrome 127.0.6533.85 和 Firefox 129.0 上。我根本无法让它在非欧盟 iOS 上运行。
提前抱歉,如果测试不够,或者我犯了一个非常明显的错误
要解决您的问题,您需要考虑以下几点:
事件监听器复制:每次单击
play
按钮时,都会添加一个新的事件监听器。这可能会导致触发多个事件侦听器,从而导致双击行为。要解决此问题,确保事件侦听器仅添加一次。
浏览器差异:不同的浏览器(例如 Google Chrome)以不同的方式处理
currentTime
属性,如 在此 StackOverflow 问题和 MDN 文档:BaseAudioContext:currentTime 属性中所述。
在本例中,您的问题是由于事件重复,您在
click
按钮上多次触发了 play
事件。这是代码:
<!doctype html>
<html>
<body>
<button id="play" disabled>play</button>
<button id="idk">load audio</button>
<script>
var clicks = 0;
console.clear();
idk = document.getElementById("idk");
idk.addEventListener("click", async () => {
aud = new Audio("https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3");
aud.addEventListener('canplaythrough', init, { once: true });
}, { once: true });
function init() {
aud.playbackRate = 0.25; // only to lengthen the audio to give you time.
playButton = document.getElementById("play");
playButton.disabled = false;
idk.innerText = "pause and set time to 1";
playButton.addEventListener("click", togglePlayPause, { once: true });
idk.addEventListener("click", setTimeToOne, { once: true });
}
function togglePlayPause() {
if (aud.paused) {
aud.play();
playButton.innerText = "pause";
} else {
aud.pause();
playButton.innerText = "play";
}
console.log(clicks++, aud.paused);
playButton.addEventListener("click", togglePlayPause, { once: true });
}
function setTimeToOne() {
console.log("Rightmost element clicked");
if (!aud.paused) {
aud.pause();
playButton.innerText = "play";
}
aud.currentTime = 1;
idk.addEventListener("click", setTimeToOne, { once: true });
}
</script>
</body>
</html>
这可确保每次点击仅调用一次
togglePlayPause
函数,从而防止出现多事件侦听器问题。