Ajax HTML5 音频播放器无法在播放第二首曲目后加载下一首曲目
Ajax HTML5 Audio Player can't load next track after second track plays
这是 post...
的后续问题
Auto load new song into HTML 5 audio player when track ends using php/jquery
感谢@Roko C. Buljan 的贡献,我能够使用以下脚本将新曲目加载到 div#player。当曲目结束时,我使用 ajax 函数 loadurl 模拟点击,然后将新曲目加载到 div#player。这播放正常,它应该在结束时加载新曲目,但它不起作用。
<script type="text/javascript">
const audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
</script>
我认为 addEventListener 无法识别通过 ajax 加载的 player.php 文件。
查看您使用的代码,我发现有很多错误:
<source>
标签应该自动关闭;
<source>
标签应该是 <audio>
标签的子标签
- tha
<audio>
标签不能有 loop
属性,否则永远不会调用 ended
事件;您甚至必须从 player.php 脚本中删除此属性。
我认为您已经从实际代码中删除了 loop
属性,否则即使是第一次也不行。
现在,问题出现是因为这一行:
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
因为您正在删除当前的音频对象并将其替换为新的。
当轨道结束时,它会在新音频对象上引发 ended
事件,该对象没有附加事件处理程序。您之前定义的事件处理程序将不再被调用。
正确的做法是不要替换音频对象,而只是将其 src
属性替换为新的曲目名称。
编辑
因此您可以将 player.php 更改为 return 不带 html 标签的文件名和其他数据,例如 json 格式:
$track = array('file'=>$file, 'image'=>$image);
echo json_encode($track);
并将以上行替换为:
var track = JSON.parse(XMLHttpRequestObject.responseText);
audio.src = track.file;
document.querySelector('#image').src = track.image;
document.querySelector('#download').href = track.file;
其中 image
和 download
是 <img/>
和 <a>download</a>
元素的 ID。
另一种选择是在每次替换 html 时重新绑定 ended
事件,但我强烈反对这种方法。不管怎样,如果你选择走这条路,你必须这样做:
function loadurl(dest, targetID) {
...
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
...
}
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
请注意audio
符号必须是可变的,不能是常量,否则无法用新的音频元素替换它的值。
这是 post...
的后续问题Auto load new song into HTML 5 audio player when track ends using php/jquery
感谢@Roko C. Buljan 的贡献,我能够使用以下脚本将新曲目加载到 div#player。当曲目结束时,我使用 ajax 函数 loadurl 模拟点击,然后将新曲目加载到 div#player。这播放正常,它应该在结束时加载新曲目,但它不起作用。
<script type="text/javascript">
const audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
</script>
我认为 addEventListener 无法识别通过 ajax 加载的 player.php 文件。
查看您使用的代码,我发现有很多错误:
<source>
标签应该自动关闭;<source>
标签应该是<audio>
标签的子标签- tha
<audio>
标签不能有loop
属性,否则永远不会调用ended
事件;您甚至必须从 player.php 脚本中删除此属性。
我认为您已经从实际代码中删除了 loop
属性,否则即使是第一次也不行。
现在,问题出现是因为这一行:
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
因为您正在删除当前的音频对象并将其替换为新的。
当轨道结束时,它会在新音频对象上引发 ended
事件,该对象没有附加事件处理程序。您之前定义的事件处理程序将不再被调用。
正确的做法是不要替换音频对象,而只是将其 src
属性替换为新的曲目名称。
编辑
因此您可以将 player.php 更改为 return 不带 html 标签的文件名和其他数据,例如 json 格式:
$track = array('file'=>$file, 'image'=>$image);
echo json_encode($track);
并将以上行替换为:
var track = JSON.parse(XMLHttpRequestObject.responseText);
audio.src = track.file;
document.querySelector('#image').src = track.image;
document.querySelector('#download').href = track.file;
其中 image
和 download
是 <img/>
和 <a>download</a>
元素的 ID。
另一种选择是在每次替换 html 时重新绑定 ended
事件,但我强烈反对这种方法。不管怎样,如果你选择走这条路,你必须这样做:
function loadurl(dest, targetID) {
...
document.getElementById(targetID).innerHTML = XMLHttpRequestObject.responseText;
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
...
}
var audio = document.querySelector('#myAudio');
audio.addEventListener("ended", () => {
loadurl.call(this,'player.php?random=1','player');
});
请注意audio
符号必须是可变的,不能是常量,否则无法用新的音频元素替换它的值。