关于javascript:如何使用jQuery将事件附加到动态HTML元素?

How do I attach events to dynamic HTML elements with jQuery?

本问题已经有最佳答案,请猛点这里访问。

假设我有一些jquery代码,它用类.myclass将事件处理程序附加到所有元素上。

例如:

1
2
3
4
5
$(function(){
    $(".myclass").click( function() {
        // do something
    });
});

我的HTML可能如下:

1
2
3
test1
test2
test3

这没问题。但是,考虑是否在将来某个时候将.myclass元素写入页面。

例如:

1
2
3
4
5
6
7
create link dynamically
<script type="text/javascript">
$(function(){
    $("#anchor1").click( function() {
        $("#anchor1").append('test4');
    });
});

在这种情况下,当用户单击a#anchor1时,会创建test4链接。

test4链接没有与之关联的click()处理程序,即使它有class="myclass"处理程序。

基本上,我想编写一次click()处理程序,并将其应用于页面加载时的内容以及稍后通过Ajax/DHTML引入的内容。我知道怎么修这个吗?


我正在添加一个新的答案,以反映稍后jquery版本中的更改。从jquery 1.7开始,不推荐使用.live()方法。

来自http://api.jquery.com/live/

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

对于jquery 1.7+,可以使用.on()将事件处理程序附加到父元素,并将与"myClass"组合的a选择器作为参数传递。

请参阅http://api.jquery.com/on/

所以不是……

1
2
3
$(".myclass").click( function() {
    // do something
});

你可以写…

1
2
3
$('body').on('click', 'a.myclass', function() {
    // do something
});

这将适用于主体中带有"myClass"的所有标记,无论是已经存在的还是以后动态添加的。

此处使用body标记,因为示例没有更接近的静态环绕标记,但发生.on方法调用时存在的任何父标记都将起作用。例如,添加了动态元素的列表的ul标记如下所示:

1
2
3
$('ul').on('click', 'li', function() {
    alert( $(this).text() );
});

只要存在ul标签,这就可以工作(还不需要存在li元素)。


有时,这样做(最高投票的答案)并不总是足够的:

1
2
3
$('body').on('click', 'a.myclass', function() {
    // do something
});

这可能是一个问题,因为触发了顺序事件处理程序。如果你发现自己这样做了,但这是因为它的处理顺序引起了问题。你可以把它包装成一个函数,当调用"刷新"监听器时。

例如:

1
2
3
4
5
6
7
8
9
function RefreshSomeEventListener() {
    // Remove handler from existing elements
    $("#wrapper .specific-selector").off();

    // Re-add event handler for all matching elements
    $("#wrapper .specific-selector").on("click", function() {
        // Handle event.
    }
}

因为它是一个函数,所以每当我以这种方式设置侦听器时,我通常在文档就绪时调用它:

1
2
3
4
5
6
$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

然后,每当添加一些动态添加的元素时,再次调用该方法:

1
2
3
4
5
6
function SomeMethodThatAddsElement() {
    // Some code / AJAX / whatever.. Adding element dynamically

    // Refresh our listener, so the new element is taken into account
    RefreshSomeEventListener();
}

希望这有帮助!

当做,


在jquery 1.7之后,首选方法是.on()和.off()。

肖恩的回答给出了一个例子。

现在表示反对:

Use the jQuery functions .live() and .die(). Available in
jQuery 1.3.x

From the docs:

To display each paragraph's text in an
alert box whenever it is clicked:

1
2
3
$("p").live("click", function(){
  alert( $(this).text() );
});

另外,LiveQuery插件也可以做到这一点,并且支持更多的事件。

< /块引用>


如果您要向DOM添加一堆锚,请改为查看事件委托。

下面是一个简单的例子:

1
2
3
4
5
6
$('#somecontainer').click(function(e) {  
  var $target = $(e.target);  
  if ($target.hasClass("myclass")) {
    // do something
  }
});

将处理程序绑定到所有当前和将来匹配的元素的事件(如单击)。也可以绑定自定义事件。

链接文本

1
2
3
4
5
$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});


您可以为所有元素将一个单击事件绑定到一个页面,无论它们是否已经在该页面上,或者是否将在将来某个时间到达,例如:

1
2
3
4
5
6
7
8
9
10
$(document).bind('click', function (e) {
   var target = $(e.target);
   if (target.is('.myclass')) {
      e.preventDefault(); // if you want to cancel the event flow
      // do something
   } else if (target.is('.myotherclass')) {
      e.preventDefault();
      // do something else
   }
});

已经用了一段时间了。很有魅力。

在jquery 1.7及更高版本中,建议使用.on()代替bind或任何其他事件委托方法,但.bind()仍然有效。


您想使用live()函数。看文档。

例如:

1
2
3
$("#anchor1").live("click", function() {
    $("#anchor1").append('test4');
});

如果您的on jquery 1.3+,则使用.live()。

Binds a handler to an event (like
click) for all current - and future -
matched element. Can also bind custom
events.