将静态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。感谢。
答案 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()
如果您使用的是旧版本,则.delegate()将适用于您:
答案 3 :(得分:0)
您可以使用on()方法http://api.jquery.com/on/
$("#my_table td").on("click", function(event){
alert($(this).text());
});