如何用jQuery替换事件处理程序?
我有一个使用AJAX导航的网站。 我有两个页面,我使用点击和拖动function
$(".myDragArea").mousedown(function(){ do stuff... mouseDrag = true; // mouseDrag is global. }); $("body").mousemove(function(){ if (mouseDrag) { do stuff... } }); $("body").mouseup(function(){ if (mouseDrag) { do stuff... mouseDrag = false; } });
我只是输入,所以请原谅任何偶然的语法错误。 该站点的两个部分使用几乎相同的代码,唯一的区别是$("body").mouseup()
函数内部。 但是,如果我访问第一部分,然后导航到第二部分,则在mouseup上运行的代码不会更改。 我已经使用firebug逐步执行代码,当第二部分加载时运行$("body").mouseup()
时没有错误或抛出。
那么,当我第二次运行$("body").mouseup()
时,为什么事件处理程序不会改变?
调用$("body").mouseup(function)
将添加一个事件处理程序。
您需要通过编写$("body").unbind('mouseup');
来删除现有的处理程序$("body").unbind('mouseup');
。
使用$("body").mouseup( ... )
将为在mouseup上触发的正文添加一个事件处理程序。
如果要添加与当前事件处理程序冲突的另一个事件处理程序,则必须先删除当前冲突的事件处理程序。
使用.unbind()可以有4个选项。 我将从最不精确到最精确的选项中列出它们:
-
Nuclear option
– 从body
删除所有事件处理程序$("body").unbind();
这非常粗糙。 让我们试着改进吧。
-
The elephant gun
– 从body
移除所有mouseup
事件处理程序$("body").unbind('mouseup');
这稍微好一点,但我们仍然可以更精确。
-
The surgeon's scalpel
– 从body
移除一个特定的事件处理程序$("body").unbind('mouseup', myMouseUpV1);
当然,对于此版本,您必须为事件处理程序设置变量。 在你的情况下,这看起来像:
myMouseUpV1 = function(){ if (mouseDrag) { do stuff... mouseDrag = false; } } $("body").mouseup(myMouseUpV1); $("body").unbind('mouseup', myMouseUpV1); $("body").mouseup(myMouseUpV2); // where you've defined V2 somewhere
-
Scalpel with anesthesia
(好吧,这个比喻穿着薄) – 你可以为绑定和解除绑定的事件处理程序创建命名空间。 您可以使用此技术绑定和取消绑定匿名函数或函数引用。 对于名称空间,您必须直接使用.bind()
方法而不是其中一个快捷方式(如.mouseover()
)。
要创建命名空间:$("body").bind('mouseup.mySpace', function() { ... });
要么
$("body").bind('mouseup.mySpace', myHandler);
然后取消绑定前面的任何一个示例,您将使用:
$("body").unbind('mouseup.mySpace');
您可以通过链接来解除多个命名空间处理程序的绑定:
$("body").unbind('mouseup.mySpace1.mySpace2.yourSpace');
最后,您可以取消绑定命名空间中的所有事件处理程序,而不管事件类型如何!
$("body").unbind('.mySpace')
您不能通过对处理程序的简单引用来完成此操作。
$("body").unbind(myHandler)
将不起作用,因为通过对处理程序的简单引用,您必须指定事件类型($("body").unbind('mouseup', myHandler)
)!
PS:您还可以使用.unbind(event)
从内部取消绑定.unbind(event)
。 如果您只想触发有限次数的事件处理程序,这可能很有用。
var timesClicked = 0; $('input').bind('click', function(event) { alert('Moar Cheezburgerz!'); timesClicked++; if (timesClicked >= 2) { $('input').unbind(event); $('input').val("NO MOAR!"); } });
当你连接处理程序时,jQUery不会“替换”事件处理程序。
如果你使用Ajax进行导航,而不是刷新整个DOM(即不在每个请求上创建一个全新的body元素),那么执行一个新的行,如:
$("body").mouseup(function(){
只是要添加一个额外的处理程序。 你的第一个处理程序仍然存在。
您需要通过调用专门删除任何处理程序
$("body").unbind("mouseUp");