代码之家  ›  专栏  ›  技术社区  ›  smfoote

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

  •  3
  • smfoote  · 技术社区  · 16 年前

    我有一个使用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 回复  |  直到 16 年前
        1
  •  3
  •   SLaks    16 年前

    打电话 $("body").mouseup(function) 添加 事件处理程序。
    您需要通过编写 $("body").unbind('mouseup'); .

        2
  •  11
  •   Peter Ajtai    16 年前

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

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

    你有4个选择 .unbind() . 我将列出从最不精确到最精确的选项:

    1. Nuclear option -从中移除所有事件处理程序 body

      $("body").unbind();
      

      这相当粗糙。让我们努力改进。

    2. The elephant gun -删除所有 mouseup 中的事件处理程序 身体

      $("body").unbind('mouseup');
      

      这有点好,但我们仍然可以更精确。

    3. The surgeon's scalpel -从中移除一个特定的事件处理程序 身体

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


    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!");
      }
    });​
    
        3
  •  1
  •   womp    16 年前

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

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

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

    只是要添加一个 额外的 处理程序。您的第一个处理程序仍然存在。

    您需要通过调用

    $("body").unbind("mouseUp");