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="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></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()调用永远不会执行。 (感谢@Daff在评论中指出)

第一个问题是,当你使用多个元素调用一个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()方法。

Live方法如何?

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

不过,你所做的关于它应该工作。 还有一个帖子看起来很相似。

晚了一点晚,但我想我会尝试清除jQuery事件处理程序中的一些常见的误解。 从jQuery 1.7起,应该使用.on()而不是弃用的.live()来将事件处理程序委托给在事件处理程序分配后的任何时候动态创建的元素。

也就是说,这不是一个简单的转换on因为语法略有不同:

新方法(例1):

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

弃用的方法(示例2):

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

如上所示,有一个区别。 扭曲是.on()实际上可以被称为类似于.live() ,通过选择器传递给jQuery函数本身:

例3:

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

但是,如果不像示例1那样使用$(document) ,则示例3将不适用于动态创建的元素。 如果您不需要动态委派,则示例3绝对没问题。

$(document).on()应该用于一切吗?

它可以工作,但是如果你不需要动态委派,那么使用例子3会更合适,因为例子1需要浏览器做更多的工作。 性能没有任何实际影响,但使用最合适的方法是有意义的。

如果不需要动态委派,应该使用.on()而不是.click()?

不必要。 以下是示例3的一个快捷方式:

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

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

参考文献:

  • jQuery文档.on()
  • jQuery文档.click()
  • jQuery文档.live()

考虑这个:

 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事件绑定到它。

最好的方法可能会 – 如建议 – 通过实时方法将其绑定到特定的类。

我相信这样做的好方法是:

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

有可能并且有时需要与元素一起创建点击事件。 这是例如基于选择器的绑定不是一个选项。 关键部分是通过在单个元素上使用.replaceWith()来避免Tobias讨论的问题。 请注意,这只是一个概念证明。

 <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> 
  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); }); }); } 
 <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>