【问题标题】:How do I replace an event handler with jQuery?如何用 jQuery 替换事件处理程序?
【发布时间】:2010-08-31 07:24:40
【问题描述】:

我有一个使用 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() 时事件处理程序没有改变?

【问题讨论】:

    标签: javascript jquery javascript-events


    【解决方案1】:

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

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

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

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

      $("body").unbind();
      

      这很粗糙。让我们努力改进。

    2. The elephant gun - 从body 中删除所有mouseup 事件处理程序

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


    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!");
      }
    });​
    

    【讨论】:

    • @SLaks - 谢谢。以前没用过这种技术。我会尝试添加它。
    【解决方案2】:

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

    【讨论】:

    • 这正是我所需要的。令人惊讶的是,我还没有遇到这个问题——或者也许我遇到了,只是我还没有真正意识到。不管怎样,谢谢。
    【解决方案3】:

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

    如果您使用 Ajax 进行导航,而不是刷新整个 DOM(即不在每个请求上创建全新的正文元素),则执行如下新行:

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

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

    您需要通过调用专门删除任何处理程序

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

    【讨论】:

    • 我正在使用 AJAX 进行导航,所以 DOM 不会重新加载,所以就是这样。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    相关资源
    最近更新 更多