以编程方式在音频元素上设置当前 Date 属性会导致事件侦听器无限期触发

Posted

技术标签:

【中文标题】以编程方式在音频元素上设置当前 Date 属性会导致事件侦听器无限期触发【英文标题】:Setting currentTime attribute programatically on audio element causes event listeners to fire indefinitely 【发布时间】:2015-10-16 04:15:31 【问题描述】:

如标题所述,以编程方式在音频元素上设置currentTime 属性时会发生此行为。设置该值后,事件侦听器会无限期地反复触发。

音频将尝试播放,但由于正在进行大量处理,音频将跳过并且我的浏览器将开始变得无响应。

我已经通过删除与currentTime 变量的绑定解决了这个问题,但我只是想问是否有人对为什么会发生这种情况有所了解?最初,这只发生在 Firefox 上,但今天它也开始发生在 chrome 上。在 safari 或 IE 11 中不会发生。

这里是一个例子:https://jsbin.com/yorawo/edit?html,console,output

想法?

<body>
  <button onclick="play()">Play</button>
  <button onclick="pause()">Pause</button>
  <audio id="audio" src="https://api.soundcloud.com/tracks/172463126/download?client_id=02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea&oauth_token=1-138878-53859839-4dcd0ce624b390"></audio>

  <script>
    var audio = document.getElementById('audio');

    // remove the line below (audio.currentTime = 0) and then try to play the audio. notice the audio plays just fine.
    // then add the line back in and notice how the console will fill up
    audio.oncanplay = function () 
      audio.currentTime = 0;
    

    audio.ontimeupdate = function () 
      console.log('why');
    

    function play() 
      audio.play();
    

    function pause() 
      audio.pause();
        
  </script>
</body>

【问题讨论】:

当你及时跳转时,在你可以玩之前有一段时间,所以你可以再次玩之后 canplay() 触发。 啊,有道理..它进入了相同事件的无限循环,一遍又一遍地触发。你救了我一辈子的挠头 【参考方案1】:

我将复制@dandavis 提到的内容:

当你及时跳转时,在你可以玩之前有一段时间,所以 canplay() 在你可以再次玩之后触发

在上面的代码块中,我将 currentTime 设置为某个值,并且我设置了 oncanplay 事件处理程序来重置该值。只要将currentTime 设置为一个值,就会触发oncanplay。由于我在oncanplay 处理程序中重置currentTime,因此该事件会无休止地发出。

【讨论】:

以上是关于以编程方式在音频元素上设置当前 Date 属性会导致事件侦听器无限期触发的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 中以编程方式设置正在“收听”的音频设备

如何以编程方式设置特定序列的音频文件?

设置音频端点设备应用程序特定(以编程方式)

以编程方式在 UITableViewCell 上设置约束

以编程方式设置控制器时“没有为***元素指定控制器”

HTML5 音频元素 - 搜索滑块 - 无法在“HTMLMediaElement”上设置“currentTime”属性:提供的双精度值是非有限的