javascript - 什么会导致点击事件多次触发?

标签 javascript jquery css

<分区>

我有一个小的待办事项 list ,用于练习。这是一个Fiddle ,我似乎无法弄清楚为什么切换在待办事项中添加和删除直通线的类的点击事件适用于某些元素,但不适用于其他元素。我检查了控制台,出于某种原因,那些不起作用的控制台在单击时会多次触发。如果有人可以告诉我为什么会发生这种情况,我将不胜感激。

// Toggle line-through todo
$('.todo-container').on('click', function(){
  $(this).toggleClass('line-through');
  console.log("fired")
})

最佳答案

就像 Mike 评论的那样,您在每次输入按键时再次向元素添加一个新的处理程序,而不是使用 event delegation


进一步说明:

当您如下所示添加事件处理程序时,jQuery 会查看 DOM 并将处理程序直接添加到任何具有 todo-container 类的元素。

$('.todo-container').on('click', function()...

$('.todo-container').click(function()...

一个重要的警告是,此只会将处理程序添加到页面上当前存在的元素。

当您意识到处理程序对新创建的(动态)元素不起作用时,您就看到了这个结果。

不太理解为什么它不起作用,您将事件绑定(bind)移动到 keyup 的处理程序中,每次创建新元素时有效地调用绑定(bind)。这似乎 起初有效,但实际上是有缺陷的,因为这再次将处理程序直接添加到任何具有 todo-container 类的元素。包括已经具有从先前调用定义的处理程序的元素。


修复一个,Event delegation (首选方法)

在下面的示例中,我们将绑定(bind)移回 keyup 处理程序之外,并使用 $('#todos').on('click', '.todo-container', 附加监听器到 '#todos' 元素(它始终存在于页面上)。然后,每当您在该元素内单击时,它都会检查您单击的子项是否具有类“todo-container”以及是否所以,将触发您的代码。这是事件委托(delegate)。这将捕获与选择器匹配的任何动态元素上的事件

$(document).on('keypress', function(e) {
  // Add todo
  if (e.which === 13 && $('.input-field').val() != "") {
    $('#todos').prepend(todoTemplate);
    var todo = $('.todo-container');
    $('#todos').children().first().find(todo).html($('.input-field').val());
    $('.input-field').val("");
  }

})



// Remove todo
$('#todos').on('click', '.todo-container-delete', function() {
    $(this).parent().remove();
  })
  // Toggle line-through todo
$('#todos').on('click', '.todo-container', function() {
  $(this).toggleClass('line-through');
  console.log("hello")
})

使用 :last 修复两个更具体的定位

您实际上可以将绑定(bind)保留在 keyup 处理程序中,如果您专门针对仅新添加的元素,如下所示:

$('#todos .todo-container:last').on('click', function(){

$('#todos .todo-container:last').click(function(){

修正三,(不推荐但可能).off()

如果您使用 .off() 从之前的元素中删除处理程序,然后再将其添加到所有元素,您也可以将绑定(bind)保留在 keyup 处理程序中,如下所示:

$('.todo-container').off().on('click', function(){

不过我会避免使用这种方法,因为如果您不专门针对要删除的处理程序(请参阅文档了解具体方法),您将删除应用于该元素的所有处理程序,这肯定会让您失望道路

关于javascript - 什么会导致点击事件多次触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39540520/

上一篇:javascript - HTML Select2 与内联按钮对齐

下一篇:javascript - 如何让Jquery事件只执行最近触发​​的事件

相关文章:

javascript - 新创建元素上的事件处理程序

javascript - Bootstrap slider - 获取值并将其显示在 div 中

html - &lt;input type ='text'/> 和 &lt;textarea&gt; 宽度有问题

javascript - 如何让固定标题在滚动 html 表中工作(当标题有多行时)

javascript - 接收数据的转换

javascript - jQuery JavaScript 数据表列压缩/挤压在一起

javascript - 在 HTML5 Canvas 上定位

javascript - jQuery .fadeOut() 阻止 div 下

javascript - 如何在页面调整大小时重新加载 jQuery 插件?

forms - Bootstrap : how do I make horizontal form's "inline-help" look better when it's too long?