JQuery 如何将 onclick 事件绑定到动态添加的 HTML 元素

我想将 onclick 事件绑定到使用 jQuery 动态插入的元素

但它从不运行绑定的函数。如果你能指出为什么这个例子不起作用,以及如何让它正常运行,我将非常高兴:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="da" lang="da">
<head>
<title>test of click binding</title>


<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">




jQuery(function(){
close_link = $('<a class="" href="#">Click here to see an alert</a>');
close_link.bind("click", function(){
alert('hello from binded function call');
//do stuff here...
});
  

$('.add_to_this').append(close_link);
});
</script>
</head>
<body>
<h1 >Test of click binding</h1>
<p>problem: to bind a click event to an element I append via JQuery.</p>


<div class="add_to_this">
<p>The link is created, then added here below:</p>
</div>


<div class="add_to_this">
<p>Another is added here below:</p>
</div>




</body>
</html>

编辑: 我编辑了这个示例,以包含两个方法插入到的元素。在这种情况下,从不执行 alert()调用。(感谢@Deff 在评论中指出这一点)

304234 次浏览

想想这个:

jQuery(function(){
var close_link = $('<a class="" href="#">Click here to see an alert</a>');
$('.add_to_this').append(close_link);
$('.add_to_this').children().each(function()
{
$(this).click(function() {
alert('hello from binded function call');
//do stuff here...
});
});
});

它将工作,因为您将它附加到每个特定的元素。这就是为什么在将链接添加到 DOM 之后,需要找到一种方法来显式地选择添加的元素作为 DOM 中的 JQuery 元素,并将 click 事件绑定到它。

最好的方法可能是——正如建议的那样——通过 live 方法将其绑定到特定的类。

我相信这样做的好处是:

$('#id').append('<a id="#subid" href="#">...</a>');
$('#subid').click( close_link );

Live 方法怎么样?

$('.add_to_this a').live('click', function() {
alert('hello from binded function call');
});

不过,你所做的看起来应该是可行的。 另一个帖子看起来非常相似。

第一个问题是,当您对一个包含多个元素的 jQuery 集调用 append 时,将为每个元素创建一个要追加的元素的克隆,从而丢失附加的事件观察器。

另一种方法是为每个元素创建链接:

function handler() { alert('hello'); }
$('.add_to_this').append(function() {
return $('<a>Click here</a>').click(handler);
})

另一个潜在的问题可能是在将元素添加到 DOM 之前附加了事件观察器。我不确定这是否有什么意义,但我认为这种行为可能被认为是不确定的。 一个更可靠的方法可能是:

function handler() { alert('hello'); }
$('.add_to_this').each(function() {
var link = $('<a>Click here</a>');
$(this).append(link);
link.click(handler);
});

所有这些方法都不推荐使用。您应该使用 on方法来解决您的问题。

如果你想定位一个动态添加的元素,你必须使用

$(document).on('click', selector-to-your-element , function() {
//code here ....
});

这取代了已经废弃的 .live()方法。

虽然有点晚了,但我还是想尝试清除 jQuery 事件处理程序中的一些常见错误观念列表。从 jQuery 1.7开始,应该使用 .on()代替不推荐的 .live(),将事件处理程序委托给在事件处理程序分配之后的任何时候动态创建的元素。

也就是说,将 live转换为 on并不简单,因为语法稍有不同:

新方法(例一) :

$(document).on('click', '#someting', function(){


});

弃用方法(例2) :

$('#something').live(function(){


});

如上所示,有一个区别。通过将选择器传递给 jQuery 函数本身,实际上可以像 .live()那样调用 .on():

例三:

$('#something').on('click', function(){


});

但是,如果不像示例1那样使用 $(document),示例3将不适用于动态创建的元素。如果您不需要动态委托,那么示例3完全可以。

$(document) . on ()应该用于所有事情吗?

它会工作,但是如果你不需要动态委托,那么使用示例3会更合适,因为示例1需要从浏览器稍微多一点的工作。这不会对性能产生任何实际影响,但是使用最适合您使用的方法是有意义的。

如果不需要动态委托,是否应该使用.on ()代替.click () ?

不一定,以下只是例子3的一个捷径:

$('#something').click(function(){


});

上面的内容是完全有效的,所以当不需要动态委托时,使用哪种方法实际上是个人偏好的问题。

参考文献:

与元素一起创建 click 事件是可能的,有时也是必要的。例如,当基于选择器的绑定不是一个选项时。关键部分是通过在单个元素上使用 .replaceWith()来避免 托拜厄斯提到的问题。请注意,这只是一个概念证明。

<script>
// This simulates the object to handle
var staticObj = [
{ ID: '1', Name: 'Foo' },
{ ID: '2', Name: 'Foo' },
{ ID: '3', Name: 'Foo' }
];
staticObj[1].children = [
{ ID: 'a', Name: 'Bar' },
{ ID: 'b', Name: 'Bar' },
{ ID: 'c', Name: 'Bar' }
];
staticObj[1].children[1].children = [
{ ID: 'x', Name: 'Baz' },
{ ID: 'y', Name: 'Baz' }
];


// This is the object-to-html-element function handler with recursion
var handleItem = function( item ) {
var ul, li = $("<li>" + item.ID + " " + item.Name + "</li>");


if(typeof item.children !== 'undefined') {
ul = $("<ul />");
for (var i = 0; i < item.children.length; i++) {
ul.append(handleItem(item.children[i]));
}
li.append(ul);
}


// This click handler actually does work
li.click(function(e) {
alert(item.Name);
e.stopPropagation();
});
return li;
};


// Wait for the dom instead of an ajax call or whatever
$(function() {
var ul = $("<ul />");


for (var i = 0; i < staticObj.length; i++) {
ul.append(handleItem(staticObj[i]));
}


// Here; this works.
$('#something').replaceWith(ul);
});
</script>
<div id="something">Magical ponies ♥</div>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(document).on('click', '.close', function(){
var rowid='row'+this.id;
var sl = '#tblData tr[id='+rowid+']';
console.log(sl);
$(sl).remove();
});
$("#addrow").click(function(){
var row='';
for(var i=0;i<10;i++){
row=i;
row='<tr id=row'+i+'>'
+   '<td>'+i+'</td>'
+   '<td>ID'+i+'</td>'
+   '<td>NAME'+i+'</td>'
+   '<td><input class=close type=button id='+i+' value=X></td>'
+'</tr>';
console.log(row);
$('#tblData tr:last').after(row);
}
});
});


</script>
</head>
<body>
<br/><input type="button" id="addrow" value="Create Table"/>
<table id="tblData" border="1" width="40%">
<thead>
<tr>
<th>Sr</th>
<th>ID</th>
<th>Name</th>
<th>Delete</th>
</tr>
</thead>
</table>
</body>
</html>
    function load_tpl(selected=""){
$("#load_tpl").empty();
for(x in ds_tpl){
$("#load_tpl").append('<li><a id="'+ds_tpl[x]+'" href="#" >'+ds_tpl[x]+'</a></li>');
}
$.each($("#load_tpl a"),function(){
$(this).on("click",function(e){
alert(e.target.id);
});
});
}