jQuery函数未绑定到新添加的dom元素


75

这是index.html

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
  <script type="text/javascript">

    $(document).ready(function() {
      $('.btn_test').click(function() { alert('test'); });
    });

    function add(){
      $('body').append('<a href=\'javascript:;\' class=\'btn_test\'>test</a>');
    }

  </script>
</head>
<body>
  <a href="javascript:;" class="btn_test">test1</a>
  <a href="javascript:;" onclick="add()">add</a>
</body>

如果单击test1链接,它将显示alert('test'),但是如果单击add链接然后单击test,则不会显示任何内容。

你能解释一下吗?


4
和10000人刚刚写下了相同的答案
阿米尔·拉明法

9
@错误的显示名称:然后修复它,不要混蛋。
scrappedcola

Answers:


213

对于2011年之后遇到此问题的用户,有一种新的正确方法可以做到这一点:

$(document).on('click', '.btn_test', function() { alert('test'); });

这是从jQuery 1.7开始。

有关更多信息,请参见直接事件和委托事件。


2
希望我可以选择答案作为“接受的答案”。感谢您保存我的(剩余的)一天!
sohaiby 2014年

1
在看到这个之前,我只是在整个项目上一直使用unbinding()和重新绑定方法。问这个的那个人呢 伙计,接受它。
不现实的2014年

迷人而酷!感谢您添加此说明。解决了我一个令人烦恼的问题。
tonejac 2015年

您应该添加解决此问题的正确方法是添加“ selector”参数。我看完链接后就知道了,但不是因为您的回答。我还是很感激:) @Moshe Katz
villancikos

$(document)很好,但是为了获得最佳性能,最好改用$(“#element”)或$(“。class”)-dom中已经存在元素或类。而不是让jquery监视整个文档,它只会监视#element或.class。
埃里克·基加西

34

您需要使用“实时”点击侦听器,因为最初只有单个元素存在。

$('.btn_test').live("click", function() { 
   alert('test'); 
});

更新:由于不推荐使用live,因此您应该使用“ on()”:

$(".btn_test").on("click", function(){ 
   alert("test");
});

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


3
是的,需要澄清的live是-是后期绑定的动态处理程序,可以在声明处理程序后将其附加到添加到DOM的元素上。有关更多信息,请参阅此文档
克里斯夫·2011年

2
另一种说明方式是:.click()仅适用于加载页面时存在的对象,而.live()适用于现在存在或将来创建的所有对象。
乔治·康明斯

我有一个新的问题,我该如何使用实时方法-> steamdev.com/zclip
Ralsk28 2011年

1
@ Ralsk28:如果此答案对您有帮助,您可以通过投票支持答案并单击检查以接受,从而奖励Pete。这也将帮助未来的站点访问者找到解决自己问题的方法。
乔治·康明斯,

1
live()现在被弃用了吗?有什么选择?
克里斯·乔布

15

我有同样的问题,例如问题,我几乎要拔头发,然后才找到解决方案。我使用了不同的语法

$(".innerImage").on("click", function(){ 
alert("test");
});

它对我不起作用(innerImage是动态创建的dom)现在我正在使用

$(document).on('click', '.innerImage', function() { alert('test'); });

http://jsfiddle.net/SDJEp/2/

谢谢@Moshe Katz


8

.click绑定到当前对jQuery可见的内容。您需要使用.live:

$('.btn_test').live('click', function() { alert('test'); });

我认为这是解决此问题的最佳方法。

7

改用Jquery live。这是它的帮助页面http://api.jquery.com/live/

$('.btn_test').live(function() { alert('test'); });

编辑:live()已弃用,应on()改为使用。

$(".btn_test").on("click", function(){ 
   alert("test");
});

.live()已过时,请使用.on()。
freeworlder

6
@silkfield我更新了答案。但下次,请提出修改建议,而不是投反对票。SO是一个社区问答论坛,我们每个人都可以改善。
阿米尔·拉明法

3

这是因为click事件仅在绑定时绑定到现有元素。您需要使用实时或委托将事件绑定到页面上现有和将来的元素。

$('.btn_test').live("click", function() { alert('test'); });

jQuery Live


2

您需要实时监听器而不是单击:

$('.btn_test').live('click', function() { 
   alert('test'); 
});

原因是click在页面加载时仅将侦听器分配给元素。添加的任何新元素都将没有此侦听器。当页面加载时以及之后添加时,Live将点击侦听器添加到元素


1

当文档加载时,您将事件侦听器添加到每个匹配的类中,以侦听那些元素上的click事件。相同的侦听器不会自动添加到稍后添加到Dom的元素中。


1

因为该事件已绑定到文档中准备好的每个匹配元素。添加的任何新元素不会自动将相同的事件绑定到它们。

添加事件后,您必须将事件手动绑定到任何新元素,或者使用实时侦听器。


1
$('.btn_test').click

将为页面上可用的元素添加处理程序(此时“测试”不存在!)

您必须在添加时手动为此元素添加点击处理程序,或者使用live事件处理程序对每个元素都适用,即使您稍后创建它也是如此。

$('.btn_test').live(function() { alert('test'); });

1

在jQuery 1.7之后可以使用method,它确实很好用

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js">
    </script>
<script>
    $(document).ready(function(){
      $("p").on("click",function(){
       alert("The paragraph was clicked.");
       $("body").append("<p id='new'>Now click on this paragraph</p>");
    });
    $(document).on("click","#new",function(){
       alert("On really works.");
      });
    });
</script>
</head>
<body>
    <p>Click this paragraph.</p>
</body>
</html>

看到它在行动 http://jsfiddle.net/rahulchaturvedie/CzR6n/


0

或者只是在页面末尾运行脚本


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.