jQuery stopPropagation被忽略

时间:2013-05-20 22:21:19

标签: javascript jquery

我的目标是阻止所有点击事件(点击时隐藏/显示HTML中的元素),除非满足某个条件(用户在输入元素中有某个单词)。

所以我尝试将该逻辑添加到文档的单击处理程序或“html”中,但是由于冒泡而首先触发了另一个元素的单击处理程序。

所以我尝试将该逻辑附加到“*”,现在点击处理程序首先触发 - 但也将其传播到另一个元素,忽略stopPropagation,preventDefault并返回false。

$(document).ready(function(){    
  $("*").click(function(event){
    if ($("#user").val() !== "admin"){
      console.log("1");
      event.stopPropagation();
      event.preventDefault();  
      return false;  
    }
  });
  $("#user").click(function(event){
    console.log("2");
    // do something
  });
});
  1. 为什么在“1”之后将“2”写入控制台,因为返回false / stopPropagation而不应该有任何进一步的传播?
  2. 如何使用jQuery实现我的目标?
  3. 谢谢!

1 个答案:

答案 0 :(得分:1)

  1. stopPropagation()可防止事件在祖先树上传播任何进一步。但是,它不会阻止触发当前剩余的事件处理程序。

    要执行 this (阻止进一步传播阻止当前元素上的任何其他事件处理程序被触发),您需要调用stopImmediatePropagation()(而不是,而不是以及)。

  2. 以这种方式将事件处理程序附加到每个元素,并且调用stopImmediatePropagation()(以及preventDefault()阻止所有点击产生效果; 提供没有事件处理程序在之前绑定(因为处理程序按顺序执行;您无法撤消已经触发的处理程序)。

    这不会使它很好,因为查找,枚举和将处理程序附加到每个元素是非常昂贵的。

    要使其更好,您的选项可以是:

    1. click个事件附加到document,然后preventDefault()并牺牲stopImmediatePropagation()

    2. 检查每个事件处理程序中#user的状态;你可以通过滚动你自己的包装函数来减轻这种痛苦;

      function checkUserState(then) {
          return function () {
              if ($("#user").val() !== "admin") {
                  then.apply(this, arguments);
              }
          };
      };
      

      ......像这样使用;

      $("#user").click(checkUserState(function(event){
          console.log("2");
      }));
      
    3. 如评论中所述,我有意避免使用事件委托的建议,因为虽然只允许附加一个事件处理程序而不是n,但它不允许您stopPropagation()事件