如何用jQuery替换事件处理程序?

时间:2010-08-30 22:13:43

标签: javascript jquery javascript-events

我有一个使用AJAX导航的网站。我有两个页面,我使用

单击并拖动功能
$(".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()时事件处理程序不会改变?

3 个答案:

答案 0 :(得分:11)

使用$("body").mouseup( ... )将为在mouseup处触发的正文添加事件处理程序。

如果要添加与当前事件处理程序冲突的另一个事件处理程序,则必须先删除当前冲突的事件处理程序。

使用.unbind()有4个选项可以执行此操作。我将从最不精确到最精确的选项中列出它们:

  1. Nuclear option - 从body

    中删除所有事件处理程序
    $("body").unbind();
    

    这非常粗糙。让我们尝试改进。

  2. The elephant gun - 从mouseup

    中删除所有body个事件处理程序
    $("body").unbind('mouseup');
    

    这稍微好一点,但我们仍然可以更精确。

  3. 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
    
  4. 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))!


  5. PS:您还可以使用.unbind(event)从内部取消绑定事件。如果您想要trigger an event handler only a limited number of times,这可能很有用。

    var timesClicked = 0;
    $('input').bind('click', function(event) {
      alert('Moar Cheezburgerz!');
      timesClicked++;
      if (timesClicked >= 2) {
        $('input').unbind(event);
        $('input').val("NO MOAR!");
      }
    });​
    

答案 1 :(得分:3)

调用$("body").mouseup(function)添加事件处理程序 您需要通过编写$("body").unbind('mouseup');来删除现有的处理程序。

答案 2 :(得分:1)

当您连接处理程序时,jQUery不会“替换”事件处理程序。

如果你使用Ajax进行导航,而不是刷新整个DOM(即不在每个请求上创建一个全新的body元素),那么执行一个新的行,如:

$("body").mouseup(function(){

只是要添加一个附加处理程序。你的第一个处理程序仍然存在。

您需要通过调用

专门删除所有处理程序
$("body").unbind("mouseUp");