jQuery多个事件处理程序-如何取消?

49

我有两个函数绑定在一个点击事件上,它们是在不同的时间绑定的(使用jQuery)。它们被触发的顺序很重要,而且它们按照正确的顺序被触发。问题是,当第一个函数返回false时,第二个函数仍然会被触发!

如何正确地取消事件?

示例代码:

$(document).click(function() { 
  alert('a');
  return false;
});

$(document).click(function() {
  alert('b');
});

当您点击页面时,仍会看到“b”警告消息。这是不可接受的!

6个回答

88

使用 jQuery 事件对象的 stopImmediatePropagation 函数。

阻止剩余的事件处理函数被执行。此方法还通过调用 event.stopPropagation() 来停止事件冒泡。

$(document).click(function(event) { 
  alert('a');
  event.stopImmediatePropagation();
  return false;
});

$(document).click(function() {
  alert('b');
});

1
你可能需要注意,为了使其正常工作,你需要使用 jQuery 1.3 及以上版本。 - Josh Stodola
如果在平板设备上先触发了touchstart事件,如果我一直按住手指,它会取消click事件的触发吗?$(document).on("touchstart click", ".myelement", function(e) {e.stopImmediatePropagtion(); //run function here})... - Alex

2

谢谢,解除绑定可以重新定义函数。

  $(document).ready(function(){
        $("#buscar_mercaderia").click(function(){ alert('Seleccione Tipo de mercaderia'); 
   });
$(".tipo").live('click',function(){
            if($(this).attr('checked')!=''){
                if($(this).val()=='libro'){
                    $("#buscar_mercaderia").unbind('click');
                    $("#buscar_mercaderia").click(function(){  window.open('buscar_libro.php','Buscar Libros', 'width=800,height=500'); });
                }else if($(this).val()=='otra'){
                    $("#buscar_mercaderia").unbind('click');
                    $("#buscar_mercaderia").click(function(){ window.open('buscar_mercaderia.php','Buscar Mercaderias', 'width=800,height=500');  });
                }
            }
        })

2

我首先要问的是:为什么你将两个函数绑定到同一个点击事件上?既然可以访问代码,为什么不将它们合并成一个函数调用呢?

$(function (){
    var callbackOne = function(e){
        alert("I'm the first callback... Warning, I might return false!");
        return false;
    };

    var callbackTwo = function(e){
        alert("I'm the second callback");
    };

    $(document).click(function (e){
        if(callbackOne(e)){
            callbackTwo(e);
        }
    });
});

4
组织。这个应用程序中有大量的JavaScript代码,它被分成了几个文件。这样,每个页面只下载必要的内容,从而导致快速的加载时间。我有一个HTTP处理程序来组合、压缩和缓存它们,因此它们都可以在一个请求中获取。 - Josh Stodola
好的。所以真的需要-1吗?只是想要帮忙...你的解释已经足够让我们知道这不是“适合你”的解决方案。 - Seb
1
抱歉!:) 不知道有谁会愿意因为给其他人可能有效的答案投反对票而浪费自己的声誉... - Seb
2
我曾经通过问“为什么你要这样做而不是那样做?”来回答过很多问题。有时候提问者并不知道或忘记考虑其他选项。 - Spencer Ruport

1

使用unbind有帮助吗?

$(document).click(function() { 
  alert('a');
  $(this).unbind('click');
  return false;
});

3
当第一个函数没有返回false时,我仍然需要触发我的第二个事件。“解绑”字面上意思是取消绑定,是否会取消绑定? - Josh Stodola
你可以将我的解决方案与Nickf的解决方案合并,这样就能得到你想要的行为 :) - fmsf
1
解绑的问题在于其他已绑定的函数将无法触发。 - Seb
2
整个方法似乎是一个俗气的变通方法!我需要一种简单的方法来取消事件,仅此而已。在常规的Javascript中,返回意味着返回,无论是true还是false。在jQuery中似乎不是这样。必须有一种使用jQuery模拟“返回”功能的方法。 - Josh Stodola
jQuery是JavaScript的库,不是一种新语言。 :p - fmsf
@Josh:没有必要这么粗鲁,收敛点。 - Paolo Bergantino

0
如果nickf所说的方法不起作用,你可以使用一个小状态机:
var trigger = 0;

$(document).click(function() { 

  alert('a');
  if(you_want_to_return_false) {
    trigger = 1;
    return false;
  }
});

$(document).click(function() {
  if(trigger !== 0) {
  alert('b');
  } 
  trigger = 0;
});

不是最美观的解决方案,但它会起作用。


嗯,我的想法“有效”,但同时也会破坏它。不过这个想法值得一试。 - nickf
这个方法的问题和另一个方法一样,只是代码更多。如果我错了,请纠正我。 - Josh Stodola

0

另一种解决方案是对函数进行去抖或节流。

这样,您可以确保尽管它触发多次,但仅在设定的持续时间内执行。这将使您的代码按原样工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接