网络开发人员变身配音演员!我正在为后者开发我的个人网站,并且在为音频文件设置自定义控件时遇到了很多问题。我正在使用以下代码加载我的音频文件......
<section id="demos widthWrap">
<?php
$aniURL = get_field('animation');
$comURL = get_field('commercial');
$demos = array(
"aniDemo" => array(
"Kind" => "Animation",
"URL" => $aniURL
),
"comDemo" => array(
"Kind" => "Commercial",
"URL" => $comURL
)
);
foreach ($demos as $demo){
?>
<figure class="demoBox">
<audio class="demo" controls preload="metadata">
<source src="<?php echo $demo["URL"];?>" type="audio/mp3">
<!-- Put a small fallback message for old browsers -->
<p>ERROR! Your browser does not support audio playback!</p>
</audio>
<ul class="demoControls">
<li class="playButton"><button class="playPause"><i class="fa-solid fa-play"></i></button></li>
<li class="progress">
<progress class="progressBar" value="0" min="0"></progress>
</li>
</ul>
</figure>
<?php
}
?>
</section>
…并且这些正在正确加载。用于自定义控件的 Javascript 会出现问题。在这里。
const supportsAudio = !!document.createElement("audio").canPlayType;
if (supportsAudio) {
const audioContaner = document.getElementsByClassName("demoBox");
const audio = document.getElementsByClassName("demo");
const audioControls = document.getElementsByClassName("demoControls");
// Hide the default controls
audio.controls = false;
// Display the user defined audio controls
audioControls.style.display = "block";
const playPause = document.getElementsByClassName("playPause");
const progress = document.getElementsByClassName("progressBar");
playPause.addEventListener("click", (e) => {
if (audio.paused || audio.ended){
audio.play();
//switch to pause icon
} else {
audio.pause();
//switch to play icon
}
});
playPause.addEventListener(ended, (e)=> {
console.log("Audio has ended");
//switch to repeat icon
});
audio.addEventListener("loadedmetadata", () => {
progress.setAttribute("max", audio.duration)
});
audio.addEventListener("timeupdate", () => {
if (!progress.getAttribute("max"))
progress.setAttribute("max", audio.duration);
progress.value = audio.currentTime;
});
}
我的大部分内容都基于这篇 MDN 文章,只挑选我需要的部分并调整音频内容。我还尝试更改一些内容以适用于音频文件的多个实例,我很确定这就是事情出现问题的地方。
将audioControls样式设置为display:block时,我收到“未捕获的类型错误:无法设置未定义的属性(设置'显示')”,但问题早在这之前就开始了。音频.controls = false;没有摆脱默认的播放控件,表明问题可能出在我的声明上。我使用 getElementsByClassName 声明的所有内容都作为 HTMLCollection (我刚刚了解到这是一个东西) 出现,并且尝试迭代其中任何一个都不会给出任何结果。我尝试了一些不同的 for…of 循环,并尝试将最高相关 DOM 元素的声明转换为数组,并尝试了 forEach ,并从我的 console.log 尝试中得到了记录。
作为专业要求,我需要将所有演示放在一页上(代理不想去多个页面听演示),并且真的不想为每个实例编写所有 Javascript音频文件。我该怎么办?
...并且尝试迭代其中任何一个都不会给出任何结果。
这就是问题所在。您正在尝试设置
HTMLCollection
的属性,它基本上是 getElementsByClassName
找到的元素列表。
这里的解决方案是选择所有
demoBox
元素并循环遍历它们。然后,对于每个 demoBox
,选择其中的所有元素并设置事件侦听器和设置。
querySelector()
和 querySelectorAll()
而不是 getElementsByClassName()
,因为它们可以更好地控制您正在寻找的内容并给出可预测的结果。它们可以在元素级别上使用,这正是我们这里所需要的。
const audioContainers = document.querySelectorAll(".demoBox");
// Loop over each .demoBox element.
for (const audioContainer of audioContainers) {
const audio = audioContainer.querySelector(".demo");
const audioControls = audioContainer.querySelector(".demoControls");
// Hide the default controls
audio.controls = false;
// Display the user defined audio controls
audioControls.style.display = "block";
const playPause = audioControls.querySelector(".playPause");
const progress = audioControls.querySelector(".progressBar");
playPause.addEventListener("click", (e) => {
if (audio.paused || audio.ended) {
audio.play();
//switch to pause icon
} else {
audio.pause();
//switch to play icon
}
});
playPause.addEventListener(ended, (e) => {
console.log("Audio has ended");
//switch to repeat icon
});
audio.addEventListener("loadedmetadata", () => {
progress.setAttribute("max", audio.duration);
});
audio.addEventListener("timeupdate", () => {
if (!progress.getAttribute("max")) {
progress.setAttribute("max", audio.duration);
}
progress.value = audio.currentTime;
});
}