Warm tip: This article is reproduced from serverfault.com, please click

javascript-html5音频播放器通过innerhtml问题刷新,带有preventdefault

(javascript - html5 audioplayer refreshed through innerhtml issue with preventdefault)

发布于 2020-11-28 16:33:26

使用Google App Script网络应用程序构建网站。有一个代码,可根据搜索关键字提取播放列表。结果格式为html列表,并使用innerhtml插入到页面的div中。

我有一个用于播放列表的脚本,其中包括preventdefault和突出显示已播放的曲目

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");
                
            });
            
            
        }

如果我在页面initailly上加载播放列表,则脚本可以工作,但是一旦我通过innerhtml方法(使用新的播放列表)更新了播放列表,我似乎就失去了脚本的统一性-当单击播放列表中的某个曲目时,它就无法播放该曲目根据浏览器默认设置在新页面中显示。

我想将audioplayer包含在innerhtml方法内(因此它会随着播放列表刷新),并且还使其在主页的另一个div中保持静态-没有效果...

   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>
Questioner
user2048695
Viewed
11
Kosh 2020-11-29 04:09:10

你需要在监听click事件的方式上更改代码
现在,你有了:

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

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

可能的解决方案是将点击样式设置为document(又称为事件委托)。从上面稍微更改一下代码行:

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

因此,每次单击任何元素时,都会检查该元素是否存在#playlist li a,如果运行,则运行指定的函数。

有关更多详细信息,请查看jQuery docs

委派的事件处理程序的优势在于,它们可以处理以后将添加到文档中的后代元素中的事件通过选择保证在附加委托事件处理程序时会出现的元素,你可以使用委托事件处理程序来避免频繁附加和删除事件处理程序的需要。例如,如果事件处理程序想要监视文档中的所有冒泡事件,则此元素可以是Model-View-Controller设计中视图的容器元素,也可以是文档。在加载任何其他HTML之前,document元素在文档的开头可用,因此可以在其中附加事件而不必等待文档准备就绪,这是安全的。