事件监听器触发多次并增加次数。

7

在一个单击函数中,我可以选择播放音频。

点击事件只触发一次(加上.off()后,我好像必须为每个单击事件都这样做,因为我认为有些基本的JavaScript工作方式我不太理解),但添加到“ended”侦听器的函数显示它正在触发按钮已单击的次数。我推测.play()也被多次触发。

这些需要在单击事件内部以获取id,那么在使用js时如何防止这些事情发生,无论是在这里还是其他地方?随处添加event.stopPropagation()event.bubbles = false.off()似乎是不必要的(而且在这种情况下也没有任何区别)。

$('.button').off().on('click', function(event){
    event.stopPropagation();
    event.bubbles = false;
    var id = $(this).attr('id')
    if ($(this).hasClass('hasAudio')) {
        document.getElementById('audio_'+id).play();
        document.getElementById('audio_'+id).addEventListener("ended", function(){
            console.log("ended");
        });
    }
});

1
因为每次单击按钮时,您都会添加事件侦听器。 - Nandu Kalidindi
5个回答

1
ended 事件移出点击事件,每次点击按钮都会注册该事件。
$('.button').on('click', function(event){
    var id = $(this).attr('id')
    if ($(this).hasClass('hasAudio')) {
        document.getElementById('audio_'+id).play();

    }
});
$('[id^="audio_"]').on("ended", function(){
    console.log("ended");
 });

1
每次单击按钮,都会向“ended”事件添加一个新的事件侦听器。为了防止这种情况,您可以尝试预先定义回调函数。这将防止事件侦听器在事件循环中一遍又一遍地添加。
匿名函数没有签名,因此当您使用它定义事件时,它会认为这是一个新的事件侦听器并多次调用它。查看工作示例以了解差异。在输入框中键入内容以查看发生了什么。
如果这很令人困惑,则“removeEventListener”可能是下一个选择。
function ended(event){
    console.log("ended");
}

$('.button').off().on('click', function(event){
    event.stopPropagation();
    event.bubbles = false;
    var id = $(this).attr('id')
    if ($(this).hasClass('hasAudio')) {
        document.getElementById('audio_'+id).play();
        document.getElementById('audio_'+id).addEventListener("ended", ended);
    }
});

var input = document.getElementById('some');


function callback(event) {
  console.log("PRINT");
}

input.addEventListener("keyup", callback)

// input.removeEventListener("keyup", callback)

input.addEventListener("keyup", callback)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="some" value="" >

匿名函数作为回调函数

var input = document.getElementById('some');

input.addEventListener("keyup", function(event) {
  console.log("PRINT");
})

// input.removeEventListener("keyup", callback)

input.addEventListener("keyup", function(event) {
  console.log("PRINT");
})
<input id="some" value="">


0

使用全局标志来定义您想要暂停还是播放,并在使用任何内联点击事件时使用preventDefault。


0

这个失败是因为每次你点击函数时,都会向按钮添加一个新的事件监听器。

        document.getElementById('audio_'+id).addEventListener("ended", function(){
        console.log("ended");

这是将事件监听器重复添加到按钮。如果您需要在单击事件内执行此操作,请检查它是否已经存在。如果已存在,则不要再次添加。


0

在任务完成后,您必须删除已注册的事件监听器。

document.getElementById('audio_'+id).removeEventListener("ended", function(){
        console.log("ended");
    });

或者你可以将注册事件监听器的逻辑移动到点击事件监听器之外。这样,事件只会被注册一次。
document.getElementById('audio_'+id).addEventListener("ended", function(){
        console.log("ended");
    });
}

$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
    document.getElementById('audio_'+id).play();
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接