将事件附加到动态生成的HTML?

EML*_*EML 2 html javascript jquery javascript-events

将静态html表转换为JavaScript生成的表时出现问题.以前,我的js/jQuery代码在表中的数据元素上设置了单击处理程序,如下所示:

$(function() {
   $('my_table td').click(function(e) {
   ...handler code
});
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我必须更改我的表,以便在JavaScript中动态生成内容:

// 'table_contents' is "<table><tbody>...</tbody></table>"
$('#my_table').html(table_contents);
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我失去了点击处理程序.我想这并不奇怪,因为我只是删除旧的HTML并用新的html替换它.但是,我不知道如何正确处理这个问题.我可以给我的匿名函数命名并在我更改html时调用它,或者我是否必须执行其他操作,例如向每个新td元素显式添加事件侦听器?在更换旧的html之后,我是否必须做任何事情来清理,比如释放旧的处理程序/监听器?js是否有内存/资源泄漏,我必须手动修复?

谢谢.

编辑

很抱歉对此感到愚蠢,但我无法获得建议的on/delegate解决方案.我的测试html是:

<div id="date_test">
<table><tbody><td>42</td></tbody></table>
</div>
Run Code Online (Sandbox Code Playgroud)

我试图以td3种不同的方式回应'42' 的点击:

$("#date_test").on("click", "td", function() {
   alert($(this).text());
});

$('#date_test').delegate('td', 'click', function() {
   alert($(this).text());
});

$(function() {
   $('#date_test td').click(function() {
      alert($(this).text());
   })
})
Run Code Online (Sandbox Code Playgroud)

其中,只有第三个起作用.请注意,这是完全静态的代码; 这是3个不同的减少测试用例.对于前两种情况,代码永远不会执行; 我可以输入语法错误而不是警报,它没有任何区别.知道我做错了什么吗?我在使用jQuery 1.7.谢谢.

Jam*_*ice 7

您可以使用该on方法将事件处理程序委托给祖先元素.假设#my_table在DOM中存在以下代码:

$("#my_table").on("click", "td", function() {
    //Do stuff
});
Run Code Online (Sandbox Code Playgroud)

on方法仅适用于jQuery 1.7+.如果您使用的是旧版本,则可以使用delegate.

这是有效的,因为DOM事件从它们起源的元素通过DOM冒泡.事件在祖先上捕获,如果原点与选择器匹配,则触发事件处理程序.

这不仅提供了处理源自最初不属于DOM的元素的事件的好处,它还可以提高性能,因为它需要较少的事件处理程序(如果将事件处理程序绑定到每个td,并且有很多td元素,这是很多事件处理程序 - 使用事件委托意味着只有一个事件处理程序.

更新(请参阅编辑问题)

您的第三个示例的工作原因是您已将代码包装在ready事件处理程序中.$(function() { ... });是简写$(document).ready(function() { ... });.

这是必要的,因为否则#date_test您要绑定事件处理程序的元素将不存在于DOM中.如果您正在执行任何DOM操作,请始终将代码放在ready事件处理程序中.

您可以将on版本或delegate版本放在就绪事件处理函数中,它应该可以工作.