动态创建的元素上的事件绑定?

我有一些代码,我正在循环遍历页面上的所有选择框,并将事件绑定到它们,以在..hovermouse on/off

这发生在页面上,并且工作正常。

我遇到的问题是,我在初始循环之后通过Ajax或DOM添加的任何选择框都不会绑定事件。

我已经找到了这个插件(jQuery Live Query插件),但是在我使用插件向我的页面添加另一个5k之前,我想看看是否有人知道一种方法来做到这一点,无论是直接使用jQuery还是通过其他选项。


答案 1

从jQuery 1.7开始,您应该使用jQuery.fn.on并填充选择器参数:

$(staticAncestors).on(eventName, dynamicChild, function() {});

解释:

这称为事件委派,其工作原理如下。该事件附加到应处理的元素的静态父级 ()。每次在此元素或其中一个后代元素上触发事件时,都会触发此 jQuery 处理程序。然后,处理程序检查触发事件的元素是否与您的选择器 () 匹配。当存在匹配项时,将执行自定义处理程序函数。staticAncestorsdynamicChild


在此之前,推荐的方法是使用 live()

$(selector).live( eventName, function(){} );

但是,在 1.7 中弃用,在 1.9 中被弃用,在 1.9 中被完全删除。签名:live()on()live()

$(selector).live( eventName, function(){} );

...可以替换为以下 on() 签名:

$(document).on( eventName, selector, function(){} );

例如,如果您的页面正在动态创建具有类名的元素,则可以将事件绑定到已经存在的父级(这是这里的问题的症结,您需要一些存在的东西来绑定,不要绑定到动态内容),这可以是(也是最简单的选项)是。虽然请记住,文档可能不是最有效的选择dosomethingdocument

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

绑定事件时存在的任何父级都可以。例如

$('.buttons').on('click', 'button', function(){
    // do something here
});

将适用于

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>

答案 2

jQuery.fn.on的文档中有一个很好的解释。

总之:

事件处理程序仅绑定到当前选定的元素;在代码调用 时,它们必须存在于页面上。.on()

因此,在下面的示例中,在生成代码之前必须存在。#dataTable tbody tr

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

如果要将新的 HTML 注入到页面中,则最好使用委托事件来附加事件处理程序,如下所述。

委派事件的优点是,它们可以处理以后添加到文档中的后代元素中的事件。例如,如果该表存在,但行是使用代码动态添加的,则下面将处理它:

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

除了能够处理尚未创建的后代元素上的事件之外,委托事件的另一个优点是,当必须监视许多元素时,它们可能会大大降低开销。在包含 1,000 行的数据表上,第一个代码示例将处理程序附加到 1,000 个元素。tbody

委托事件方法(第二个代码示例)将事件处理程序仅附加到一个元素,即 ,并且事件只需要向上冒泡一个级别(从单击到 )。tbodytrtbody

注意:委派事件不适用于 SVG