提问者:小点点

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


我有一段代码,我循环浏览页面上的所有选择框,并将.hover事件绑定到这些框上,以便在鼠标打开/关闭上对它们的宽度进行一些调整。

这发生在page ready上,并且运行良好。

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

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


共3个答案

匿名用户

从jQuery1.7开始,您应该使用jQuery.fn.on:

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

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

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

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

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

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

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

例如,如果您的页面正在动态创建具有类名doSomething的元素,您将把事件绑定到已经存在的父级(这是这里问题的核心,您需要绑定到已经存在的东西,而不是绑定到动态内容),这可以是(也是最简单的选项)document。 但是请记住文档可能不是最有效的选项。

$(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>

匿名用户

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

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

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

注意:委托事件不适用于SVG。

匿名用户

这是一个纯JavaScript解决方案,没有任何库或插件:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

其中HasClass

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

现场演示

这要归功于Dave和Sime Vidas

使用更现代的JS,hasClass可以实现为:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

相关问题