Javascript `结束了Firefox 87、88和89中无休止地触发的事件
我创建了一个小脚本来重现这个问题Javascript `结束了Firefox 87、88和89中无休止地触发的事件,javascript,firefox,audio,Javascript,Firefox,Audio,我创建了一个小脚本来重现这个问题 const audio = document.createElement( 'audio' ) let i = 0 audio.onended = (e) => { i++ requestAnimationFrame( () => console.log( `ended ${i} time${i>1?'s':''}, audio is ${audio.paused?'':'not '}paused`) ) } audio.onc
const audio = document.createElement( 'audio' )
let i = 0
audio.onended = (e) => {
i++
requestAnimationFrame( () => console.log( `ended ${i} time${i>1?'s':''}, audio is ${audio.paused?'':'not '}paused`) )
}
audio.oncanplaythrough = (e) => {
audio.pause()
audio.currentTime = audio.duration
}
audio.src = 'https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3'
该脚本创建一个audio
元素、一个oneded
回调函数,该函数在控制台中打印事件被触发的次数,以及一个oncanplaythrough
回调函数,该函数通过编程将currentTime
设置为音频文件的duration
。在oneded
回调函数中,我引入了requestAnimationFrame
调用,其唯一目的是防止浏览器因Firefox中触发大量end
事件而失去响应
脚本一运行,就可以验证Firefox是否无休止地触发结束
事件,尽管音频元素已暂停。这种行为发生在Firefox 87以及Firefox Beta 88.0b9和Firefox每晚89.0a1中
在Chrome和Edge中,只要触发canplaythrough
,就会触发一次end
事件,从而将currenTime
设置为文件的结尾
在Safari中,从不触发end
事件,考虑到音频元素已暂停
,并且currentTime
以编程方式设置为文件结尾,我认为这应该是预期的行为
Chrome/Edge和Safari中行为的区别在于解释:
当播放或流媒体已停止时,将触发结束事件,原因是已到达媒体的结尾或没有其他可用数据
根据该定义,Safari似乎是实现正确行为的唯一浏览器:如果音频元素被暂停,只需在文件末尾设置currentTime
,就不会触发任何ended
事件,因为音频元素:
currentTime
是以编程方式设置的,因此未到达文件末尾事件
——就像Firefox中发生的那样——都不是预期的行为,尤其是当音频元素暂停时
我是否遗漏了什么,或者这是Firefox中的一个bug
更新
我最初发布的脚本有点误导,因为设置currentTime
总是触发canplaythrough
事件。因此,oncanplaythrough
回调递归地触发自身。但是不同浏览器之间的不同行为是因为Firefox是唯一一个audio.currentTime=audio.duration
会触发end
事件的浏览器,即使audio.currentTime
已经等于audio.duration
我创建了一个片段来测试不同浏览器之间的差异
const audio=document.querySelector(“#demo”)
const button=document.querySelector(“#jump”)
const output=document.querySelector(“#output”)
设i=0
button.onclick=(e)=>{
audio.currentTime=audio.duration
}
audio.onended=(e)=>{
我++
常量p=document.createElement('p')
p、 innerHTML=`曲目结束${i}时间${i>1?'s':'}`
output.innerHTML=p.outerHTML
}
body{font-family:sans-serif;}
反复单击“跳到终点”按钮
在Safari中,除非玩家当前正在玩,否则不会触发任何end
事件。一旦播放机到达音频文件的末尾,将不再生成end
事件
在Chrome/Edge中,结束
事件只触发一次,无论玩家正在玩或暂停
在Firefox中,end
事件会在每次单击按钮时触发,而不管播放器正在播放或暂停
跳到底