Javascript音频分层eventListener HTML5在多次迭代中失败

Javascript audio layering eventListener HTML5 fails on multiple iterations

本文关键字:迭代 失败 音频 分层 eventListener HTML5 Javascript      更新时间:2023-09-26

我正在制作一个音频函数,用于一个简单的脚本,以播放钢琴上的音符。对于音频标签在播放完之前无法处理新请求的问题,我的解决方案是为随后的每次点击创建一个新的音频元素,然后设置监听器在播放完声音后删除该元素。它工作得很好,只是我的事件侦听器似乎被覆盖了,所以只跟踪声音的最后一次迭代,使许多音频元素保持完整和不活动。

代码:

var x = 0;
function playSound(){
  x = x + 1;
  var na = document.createElement('audio');
  na.setAttribute('id','cycle'+x);
  document.body.appendChild(na);
  var ta = document.getElementById('cycle'+x);
  var ns = document.createElement('source');
  ns.setAttribute('src','notify.wav');
  ta.appendChild(ns);
  document.getElementById('cycle'+x).addEventListener('ended', function(){
  document.body.removeChild(document.getElementById('cycle'+x));
    try{document.getElementById('cycle'+x).remove();}
    catch(err){}});
  ta.play();
}

并将声音预加载到页面中:

<audio id="preloader" preload="auto"><source src="notify.wav"></source></audio>

我希望每个生成的音频元素都有单独的事件侦听器,这样当文件播放后,该元素就会被删除。

您的问题源于引用问题-通过示例代码中使用的方法,您无法在侦听器的当前范围中获取所需的元素。

Safari的控制台告诉我:

[Error] NotFoundError: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
(anonymous function) (_display, line 33)

显然,所有事件侦听器都正确启动。

当然,你可以进行大规模的搜索,以找到背后的真正原因,但既然你正在寻找解决问题的方法,这应该做到:

删除这些行:

document.body.removeChild(document.getElementById('cycle'+x));
try{document.getElementById('cycle'+x).remove();}
catch(err){}});

并将其替换为:

this.remove();

事件侦听器回调将始终以this的形式提供相关元素。这是获得有效推荐人的最安全途径。