我现在有一个问题,我正在使用slidetoggle来隐藏/显示我的主导航:
$("#menu_block_button").click(function(){
$("nav #block-menu-block-2 > div > div > ul").slideToggle();
})
在我在页面上加载ajax之前一切正常。在那之后它会执行两次切换。我假设在ajax之后再次加载脚本。
在触发事件之前,我该怎么做才能删除它?
答案 0 :(得分:1)
如果那是该特定元素的唯一侦听器,并且问题是AJAX,那么在您的AJAX请求的成功函数结束时,添加以下代码:
$("#menu_block_button").off();
$("#menu_block_button").click(function(){
$("nav #block-menu-block-2 > div > div > ul").slideToggle();
})
这将删除附加到元素的所有事件侦听器,并添加您想要的那个。但是,如果它仍然发生两次,那么你必须在那里添加事件监听器的代码,所以只需在你的成功函数中添加这段代码:
$("#menu_block_button").off();
答案 1 :(得分:0)
绑定和取消绑定处理程序可能会带来麻烦。使用委托事件要好得多。
事件从DOM树中的元素自下而上发送。委托事件处理程序附加到将触发已处理事件的元素的容器。当事件被触发时,它不会在元素本身中处理,而是在它到达必须处理它的容器之前冒泡。所以容器负责处理事件。 (容器“知道”哪个元素触发了事件,因此它可以决定是否处理它,具体取决于选择器)。
如果选择一个未被AJAX更新替换的容器,则在ajax更新后,您不必担心绑定和解除绑定处理程序。
你是怎么做到的?这取决于jQuery版本。
过去是.live()
或者最好是.delegate()
.live():为现在和将来与当前选择器匹配的所有元素附加事件处理程序。 (在1.7中弃用,在1.9中删除)
.delegate():根据一组特定的根元素,为现在或将来与选择器匹配的所有元素的一个或多个事件附加一个处理程序。
现在,推荐的方法是on()
:
.on():将一个或多个事件的事件处理函数附加到所选元素。
要使用on()
,您必须这样做:
$('container selector').on('event','triggers selector', 'handler')
例如,要使用函数clicked
来处理ID为a
的div中的所有链接(navbar
元素):
$('div#navbar').on('click', 'a', clicked);
您只能拨打一次此电话,如果未在AJAX更新中更新导航栏div,它将继续工作。 (如果更新了这个div,选择一个不是的外部元素!你可以随时选择正文,但最好尽可能接近触发器来处理它)
注意:如果您在任何时候使用event.stopPropagation()
,事件将停止冒泡DOM树。如果您没有调用它,并且同一事件还有任何其他委派事件,则将再次处理该事件。
注意:这对于处理可由许多不同元素触发的事件也很有意义。例如,如果你有一个表,有许多行,每个行都有几个链接,并且想要处理这个链接上的点击,最好将单个处理程序绑定到表而不是绑定所有这些的触发器。元件。
答案 2 :(得分:0)
绑定和解除绑定此元素是一个创可贴。 IMO你应该审核你的代码并重构它,这样它就不会被执行两次。否则,您可能会遇到许多其他不利影响。如果你发布你的代码,我可以告诉你麻烦在哪里。