我有一段代码,我循环浏览页面上的所有选择框,并将.hover
事件绑定到这些框上,以便在鼠标打开/关闭
上对它们的宽度进行一些调整。
这发生在page ready上,并且运行良好。
我遇到的问题是,我在初始循环之后通过Ajax或DOM添加的任何选择框都不会绑定事件。
我已经找到了这个插件(jQuery Live Query插件),但是在我用一个插件向我的页面添加另外5K之前,我想看看是否有人知道这样做的方法,无论是直接使用jQuery还是通过其他选项。
从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
,并且事件只需要向上冒泡一个级别(从单击的tr
到tbody
)。
注意:委托事件不适用于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);
}