向页面添加更多可点击元素然后.on()不起作用

时间:2013-10-24 06:44:41

标签: javascript jquery

所以我在一个像这样的页面中有一些代码

<div id="main">
  <div class='module' id ='test1'>1</div> 
  <div class='module' id ='test2'>2</div>
  <div class='module' id ='test3'>3</div>
  <div class='module' id ='test4'>4</div>
</div>

和一些在document.load上有事件的js

$('.module').on("click", function(){
  if ($(this).hasClass('flipped')) {
    $(this).toggleClass('flipped');   
  } else {
      $('.module').removeClass('flipped');
      $(this).toggleClass('flipped');
  }  
}); 

这可以正常工作,直到动态添加元素,所以我想添加

  <div class='module' id ='test5'>5</div>

这不是可点击的,因为.on没有绑定到这个..

我在这里阅读的帖子解释说.on不会工作......但我找不到解决方案..

任何人都可以帮忙吗?

3 个答案:

答案 0 :(得分:4)

将事件委派给父#main

$('#main').on("click", ".module", function(){
  if ($(this).hasClass('flipped')) {
    $(this).toggleClass('flipped');   
  } else {
      $('.module').removeClass('flipped');
      $(this).toggleClass('flipped');
  }  
}); 

答案 1 :(得分:2)

您的JavaScript代码仅在页面加载时执行。因此,在加载页面后,您的代码将被执行,并告诉它将onclick事件处理程序附加到具有类module的元素。在初始页面加载期间,只有4个这样的元素。因此,事件处理程序将仅附加到这些元素(非常抽象地说)。

现在,当动态添加新元素时,事件不会触发,因为没有处理程序绑定它们。

在这种情况下,您应该利用事件委派。您需要将事件处理程序绑定到封闭元素(#main或某些使用body)。

所以你的代码就像:

$('#main').on("click", ".module", function(){
  if ($(this).hasClass('flipped')) {
    $(this).toggleClass('flipped');   
  } else {
      $('.module').removeClass('flipped');
      $(this).toggleClass('flipped');
  }  
}); 

因此,事件将仅与静态#main相关联,但是当事件发生时,它知道在哪里找到目标元素,因为您已将目标指定为.module

看看这个:

  

http://api.jquery.com/on/

事件处理程序仅绑定到当前选定的元素;它们必须存在于您的代码调用.on()时页面上。 要确保元素存在且可以选择,请在文档就绪处理程序中为元素执行事件绑定在页面上的HTML标记中。如果将新HTML注入页面,请在将新HTML放入页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序,如下所述。

委托事件的优势在于它们可以处理来自稍后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委派事件来避免频繁附加和删除事件处理程序的需要。例如,此元素可以是模型 - 视图 - 控制器设计中视图的容器元素,如果事件处理程序想要监视文档中的所有冒泡事件,则可以是文档。在加载任何其他HTML之前,文档元素在文档的头部可用,因此可以安全地将事件附加到那里而无需等待文档准备就绪。

除了能够处理尚未创建的后代元素上的事件之外,委派事件的另一个优点是,当必须监视许多元素时,它们可能会有更低的开销。在其tbody中包含1,000行的数据表中,此示例将处理程序附加到1,000个元素:

$( "#dataTable tbody tr" ).on( "click", function() {
  alert( $( this ).text() );
});

委托事件方法只将一个事件处理程序附加到一个元素tbody,而事件只需要冒出一个级别(从点击的tr到tbody):

$( "#dataTable tbody" ).on( "click", "tr", function() {
  alert( $( this ).text() );
});

注意:委派事件不适用于SVG。

答案 2 :(得分:1)

试试这个......

$('body').on("click", ".module" , function(){