如何将 eventListener 函数添加到具有唯一 ID 的元素?
How to add eventListener function to elements with unique id?
我有一些动态卡片:
并且我想将 eventListener 添加到所有播放按钮(它们的代码是):
<a href="link">
<img src="play.svg">
<audio src="myMusic.mp3"></audio>
</a>
当我点击“播放”时,它应该如下所示:
(它应该改变图像并且还应该播放音频)
到目前为止我的 JS 代码是:
<script>
var imgsPlay = document.getElementsByClassName('play-img-loop');
var audioPlayers = document.getElementsByClassName('audio-player');
window.onload = function() {
for(var i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
this.setAttribute('src', "img/icons/play_red.svg");
audioPlayers[i].play();
} else if(this.getAttribute('src') == "img/icons/play_red.svg") {
this.setAttribute('src', "img/icons/play.svg");
audioPlayers[i].pause();
}
});
}
}
</script>
(我可以手动完成,但是)不能动态。我该怎么做?
你需要委托!如果不是,那么你的问题只是 JavaScript closure inside loops – simple practical example
的骗局
这里我假设你有一个名为 cardContainer 的容器
我对 _red 表示播放或暂停有点困惑,所以更改下面的代码以匹配。您的示例 HTML 与您显示的代码不匹配,播放器和图像上没有 类,因此我假设您在实际代码中确实有这些
window.addEventListener('load', function() {
document.getElementById('cardContainer').addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.classList.contains('play-img-loop')) {
const src = tgt.getAttribute('src');
const running = src.includes('_red');
const audioPlayer = tgt.closest('a').querySelector('audio');
tgt.setAttribute('src', `img/icons/play$(running?'':'_red').svg`);
if (running) audioPlayer.pause();
else audioPlayer.play();
}
});
});
您的问题是对闭包的处理不正确。事件侦听器回调永远不会按照您编写的方式获得 i
的正确值。 i
的值将始终是触发事件时的最后一个。
最简单的解决方法是只为单次迭代的范围定义变量 i
- 这就是 let
所做的。
for(let i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
...
}
有用参考:setTimeout in for-loop does not print consecutive values
我有一些动态卡片:
并且我想将 eventListener 添加到所有播放按钮(它们的代码是):
<a href="link">
<img src="play.svg">
<audio src="myMusic.mp3"></audio>
</a>
当我点击“播放”时,它应该如下所示:
(它应该改变图像并且还应该播放音频)
到目前为止我的 JS 代码是:
<script>
var imgsPlay = document.getElementsByClassName('play-img-loop');
var audioPlayers = document.getElementsByClassName('audio-player');
window.onload = function() {
for(var i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
this.setAttribute('src', "img/icons/play_red.svg");
audioPlayers[i].play();
} else if(this.getAttribute('src') == "img/icons/play_red.svg") {
this.setAttribute('src', "img/icons/play.svg");
audioPlayers[i].pause();
}
});
}
}
</script>
(我可以手动完成,但是)不能动态。我该怎么做?
你需要委托!如果不是,那么你的问题只是 JavaScript closure inside loops – simple practical example
的骗局这里我假设你有一个名为 cardContainer 的容器
我对 _red 表示播放或暂停有点困惑,所以更改下面的代码以匹配。您的示例 HTML 与您显示的代码不匹配,播放器和图像上没有 类,因此我假设您在实际代码中确实有这些
window.addEventListener('load', function() {
document.getElementById('cardContainer').addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.classList.contains('play-img-loop')) {
const src = tgt.getAttribute('src');
const running = src.includes('_red');
const audioPlayer = tgt.closest('a').querySelector('audio');
tgt.setAttribute('src', `img/icons/play$(running?'':'_red').svg`);
if (running) audioPlayer.pause();
else audioPlayer.play();
}
});
});
您的问题是对闭包的处理不正确。事件侦听器回调永远不会按照您编写的方式获得 i
的正确值。 i
的值将始终是触发事件时的最后一个。
最简单的解决方法是只为单次迭代的范围定义变量 i
- 这就是 let
所做的。
for(let i = 0; i < imgsPlay.length; i++) {
imgsPlay[i].addEventListener('click', function(event) {
if(this.getAttribute('src') == "img/icons/play.svg") {
...
}
有用参考:setTimeout in for-loop does not print consecutive values