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

Why when initiating $.click() several times, and if the link is clicked once, it captures it more than once?

本文关键字:一次 不止一次 单击 链接 click 为什么 启动 如果      更新时间:2023-09-26

我有一些像:

function init(){
  $('.btn').click(function(){
    //do something;
  }
}

当通过ajax添加新内容时,我调用init(),以便单击事件适用于新按钮。但是当我单击它一次时,它会捕获几次点击(与我调用init()的次数一样多)。这是有道理的,但如何避免呢?

jsFiddle链接:http://jsfiddle.net/s2ZAz/8/


解决方案:
*使用$.delegate() - http://api.jquery.com/delegate/
*使用$ .live()——http://api.jquery.com/live/

不太受欢迎,但仍然是解决方案:
*使用$ .off .unbind美元()——http://api.jquery.com/off/或http://api.jquery.com/unbind/()——

click表示,"对于每个匹配选择器的对象,连接此单击侦听器"。您可能想要更像delegate的东西,它说"对于每个将匹配此选择器的对象,连接此侦听器"。

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

如果你调用init两次,你仍然会得到两次回调,但是在这种方式下,你不会有调用init两次,因为当添加新对象时,它们已经被分配给点击监听器。

注意上面的document应该被替换为最近的持久祖先,按照Greg下面的评论。

演示。

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

演示。

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

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

$("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/>");

试一试

正如David所提到的,并且根据liho的委托示例(喜欢fiddle级联警报弹出多少次的方式!!),问题在于多个绑定,可以使用.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!');
});