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

时间:2012-02-03 10:51:25

标签: javascript jquery html javascript-events

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

$(function() {
   $('my_table td').click(function(e) {
   ...handler code
});

这很好,但是我必须更改我的表,以便在JavaScript中动态生成内容:

// 'table_contents' is "<table><tbody>...</tbody></table>"
$('#my_table').html(table_contents);

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

感谢。

修改

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

<div id="date_test">
<table><tbody><td>42</td></tbody></table>
</div>

我试图以3种不同的方式回复td'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());
   })
})

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

4 个答案:

答案 0 :(得分:7)

您可以使用on方法将事件处理程序委派给祖先元素。假设DOM中存在#my_table,则执行以下代码:

$("#my_table").on("click", "td", function() {
    //Do stuff
});

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

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

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

更新(请参阅编辑问题)

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

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

您可以将on版本或delegate版本置于就绪事件处理函数中,它应该可以正常工作。

答案 1 :(得分:1)

我最近遇到了同样的问题。事实证明,加载JS后进入页面的元素不会附加事件。 我使用委托http://api.jquery.com/delegate/轻松解决了这个问题。它通过父元素向上传播事件,直到它们被捕获并执行。诀窍是确保将事件委托给第一次加载js时始终存在的元素,因此在该容器中添加的任何新元素都将捕获它们的事件。

$('#container').delegate('#my_table td', 'click' (function(e) {...

答案 2 :(得分:0)

根据您使用的jquery版本,您可以尝试使用jquery .on()

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

如果您使用的是旧版本,则.delegate()将适用于您:

http://api.jquery.com/delegate/

答案 3 :(得分:0)

您可以使用on()方法http://api.jquery.com/on/

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