为什么在多次启动$ .click()时,如果链接被点击一次,它会多次捕获它?

时间:2011-12-04 19:06:55

标签: javascript jquery ajax onclick buttonclick

我有类似的东西:

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/

4 个答案:

答案 0 :(得分:2)

如果您使用新的jQuery 1.7语法来附加处理程序,则可以使用unbind方法删除事件处理程序(或off方法)

更好的是,您可以使用live方法为将来添加到页面的任何元素设置事件处理程序,并匹配给定的选择器。这样你只需要调用一次init。

答案 1 :(得分:2)

click说,“对于匹配选择器的每个对象,挂钩此单击侦听器”。你可能想要更像delegate的东西,说“对于每个与这个选择器匹配的对象,挂钩这个监听器”。

$(document).delegate('button', 'click', function() {
});

如果你拨打init两次,你仍然可以获得双重回调,但是通过这种方式,你不会 两次调用init,因为新对象是补充说,他们已经被分配给点击听众。

请注意,上面的document应该替换为最近的持久性祖先,根据Greg的评论如下。

Demo

从jQuery 1.7开始,你最好使用the .on() function来达到同样的效果。

Demo

答案 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/>");

Try it out

答案 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!');
});