<a id="link_foo">Foo</a><a id="link_foo">Foo</a>
<script type="text/javascript">
function bindFooClick(){
$("#link_foo").click(function(){
console.log "asd"
});
}
bindFooClick();
bindFooClick();
bindFooClick();
bindFooClick();
</script>
然后去点击 Foo 这个连接,将会出现 4 个日志输出。
如果不小心这个事件绑定被搞得成倍增长了,那就等着暴掉吧。
所以需要在 bindFooClick
绑定事件前去掉之前的绑定
function bindFooClick(){
$("#link_foo").unbind("click");
$("#link_foo").bind("click", function(){
console.log "asd"
});
}
不知道 jQuery 有没有自带类似防止重复绑定事件的函数。
没遇到过类似的情况,不过刚才翻了一下 jquery,有这么一段——
jQuery.each(["bind", "one"], function( i, name ) {
......
if ( name === "one" ) {
handler = function( event ) {
jQuery( this ).unbind( event, handler );
return fn.apply( this, arguments );
};
handler.guid = fn.guid || jQuery.guid++;
} else {
handler = fn;
}
......
所以你可以试试用 one 代替 bind,good luck :-)
@huacnlee 这个问题是由于 jQuery 重复绑定事件导致的。bind() 在向里添加绑定,而不检查是否相同. 不要重复执行绑定操作,但如果是无法改掉,可以使用 $().unbind().bind() 来处理比较方便. 至于 @fwword 说的 $.one 是只触发一次后被清除,应该不满足此需求. 推荐看看http://www.w3school.com.cn/jquery/jquery_ref_events.asp 这个 jQuery 的事件列表。
还有一个类似的函数,die() 与 live() 在 jQuery 中叫委托事件,是说新生成的节点仍然可以触发此消息。
@huacnlee JavaScript 本身不带重复的 event callback 检测,这部分逻辑 jQuery 也不应该自带,你这里绑定的是一个匿名的 function,交给 jQuery 或者 JS 本身来防止重复 binding 就不合理了,应该是你的 App 自己来 handle 这类 binding。
这里有个项目是我刚刚 Google 到的,看看能不能配合你的 App 一起来防止对同一个 Dom element 重复绑定同样的 event callback。 https://github.com/sebastien-p/jquery.hasEventListener
不过对我来说这个需求基本不存在,自从 jQuery 完善了它的 live()
和 delegate()
之后,我全部通过 delegate 来完成所有的 event handler,效率高且便于维护。
#5 楼 @edokeh 谢谢,jQ 的发展真迅猛,顺便找到一篇文章解释的非常详细关于用 on 和 off 替换调 live, delegate, bind 等方法。 http://www.andismith.com/blog/2011/11/on-and-off/
handler 监听事件不要匿名,在绑定前先解绑:
$( ELEM ).unbind( 'click', handler_name ).bind( 'click', handler_name );
最近又了解了一种写法:
$( ELEM ).unbind( 'click.biz' ).bind( 'click.biz', function(){ });//事件也有命名空间