html5 音频播放器通过 preventdefault 的 innerhtml 问题刷新

html5 audioplayer refreshed through innerhtml issue with preventdefault

使用 Google App Script 网络应用构建网站。 有一个根据搜索关键字获取播放列表的代码。结果被格式化为 html 列表并使用 innerhtml.

插入页面上的 div

我有一个播放列表脚本,其中包括防止默认和突出显示播放曲目

audioPlayer();
        function audioPlayer(){
            var currentSong = 0;
            $("#audioPlayer")[0].src = $("#playlist li a")[0];
            $("#playlist li a").click(function(e){
                e.preventDefault();
                $("#audioPlayer")[0].src = this;
                $("#audioPlayer")[0].play();
                $("#playlist li").removeClass("current-song");
                currentSong = $(this).parent().index();
                $(this).parent().addClass("current-song");
                
            });
            
            
        }

如果我一开始用页面加载播放列表,脚本就可以工作,但是一旦我通过内部 html 方法(使用新播放列表)更新播放列表,我似乎失去了脚本功能 - 当点击其中一个时播放列表中的曲目默认按照浏览器默认设置在新页面中播放曲目。

我尝试将音频播放器包含在内部html 方法中(因此它会随播放列表一起刷新)并在主页上的另一个 div 中保持静态 - none 有效...

   function fnResults(resultsData){

  // resultsData is html formated list of mp3 files, "playlistContainer" is the div being populated by the innerHtml
  
  document.getElementById("playlistContainer").innerHTML = '<audio class="AudioPlayer" src="" controls id="audioPlayer"></audio><ul id="playlist"><li class="current-song">' + resultsData +'</ul>';
  
  //in this example the audioplayer is being loaded with the playlist
  
  }
  
       // this is the script to control the audioPlayer
       
       audioPlayer();
        function audioPlayer(){
            var currentSong = 0;
            $("#audioPlayer")[0].src = $("#playlist li a")[0];
            $("#playlist li a").click(function(e){
                e.preventDefault();
                $("#audioPlayer")[0].src = this;
                $("#audioPlayer")[0].play();
                $("#playlist li").removeClass("current-song");
                currentSong = $(this).parent().index();
                $(this).parent().addClass("current-song");
            });
        }

这是“resultsData”的示例值:

<a href=http://www.digitalhistory.uh.edu/music/marines_hymn_us_marine_band1998.mp3>1st Track Name - Artist Name</a></li><li><a href=http://www.digitalhistory.uh.edu/music/marines_hymn_us_marine_band1998.mp3>2nd Track Name - Artist Name</a></li>

您需要更改监听 click 事件的代码。
所以现在你有:

$("#playlist li a").click(function(e){

这意味着 “现在获取所有 #playlist li a 的元素并在其上设置点击侦听器”。
DOM 中出现的元素稍后在您更新播放列表时将不会被考虑在内。

可能的解决方案是将 click litener 设置为 document(也称为事件委托)。只需稍微更改上面的代码行:

$(document).on("click", "#playlist li a", function(e){

所以每次点击任何元素时,都会检查该元素是否#playlist li a,如果是运行指定的函数。

详情请看jQuery docs:

Delegated event handlers have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated event handlers to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.