我有类似的东西:
function init(){
$('.btn').click(function(){
//do something;
}
}
当通过ajax添加新内容时,我正在调用init()
,因此click事件适用于新按钮。但是当我点击它一次时,它会捕获几次点击(就像我调用init()
一样多次)。这是有道理的,但如何避免呢?
jsFiddle链接:http://jsfiddle.net/s2ZAz/8/
的解决方案:
*使用$ .delegate() - http://api.jquery.com/delegate/
*使用$ .live() - http://api.jquery.com/live/
不太优选但仍然是解决方案:
*使用$ .off() - http://api.jquery.com/off/或$ .unbind() - http://api.jquery.com/unbind/
答案 0 :(得分:2)
如果您使用新的jQuery 1.7语法来附加处理程序,则可以使用unbind
方法删除事件处理程序(或off
方法)
更好的是,您可以使用live
方法为将来添加到页面的任何元素设置事件处理程序,并匹配给定的选择器。这样你只需要调用一次init。
答案 1 :(得分:2)
click
说,“对于匹配选择器的每个对象,挂钩此单击侦听器”。你可能想要更像delegate
的东西,说“对于每个与这个选择器匹配的对象,挂钩这个监听器”。
$(document).delegate('button', 'click', function() {
});
如果你拨打init
两次,你仍然可以获得双重回调,但是通过这种方式,你不会 两次调用init
,因为新对象是补充说,他们已经被分配给点击听众。
请注意,上面的document
应该替换为最近的持久性祖先,根据Greg的评论如下。
从jQuery 1.7开始,你最好使用the .on()
function来达到同样的效果。
答案 2 :(得分:1)
$("body").delegate("button", "click", function() {
alert('I\'m annoying!');
});
$('div').append("<button>Click me, I will alert twice</button><br/>");
$('div').append("<button>Click me, I will alert once</button><br/>");
$('div').append("<button>Click me, I will not alert at all</button><br/>");
答案 3 :(得分:0)
正如大卫所提到的那样,并且按照liho的委托示例(喜欢小提琴的方式级联警报弹出的次数!!),问题在于多个绑定,可以用.live()
解决(已弃用)或.delegate()
(逐步淘汰)或.on()
(首选)。但是,在性能方面委托听取文档甚至body
节点是错误的。
更好的方法是确定永远不会被销毁的按钮的祖先。 body
是一个简单的选择,但几乎总是这样我们使用某种类型的包装器元素构建我们的页面,这些元素嵌套了比body
更深的一个或多个级别,因此允许您设置更少的侦听器
HTML:
<div id="someWrapper">
<div class="somethingThatGetsDestroyed">
<button>Click Me</button>
</div>
</div>
JS使用jQuery 1.7 +:
$('#someWrapper').on('click', 'button', function() {
alert('Clickity-click!');
});