jQuery stopPropagation is ignored

jQuery stopPropagation is ignored

本文关键字:ignored is stopPropagation jQuery      更新时间:2023-09-26

我的目标是防止所有的点击事件(当点击时隐藏/显示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实现我的目标?

谢谢!

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

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

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

    这并不能使很好,因为查找、遍历和为每个元素附加处理程序的成本相当高。

    要使更美观,的选项是:

    1. click事件附加到document上,并简单地将preventDefault()和牺牲stopImmediatePropagation()

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

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

      …使用like so;

      $("#user").click(checkUserState(function(event){
          console.log("2");
      }));
      

    正如评论中所指出的,我有目的地避免使用事件委托的建议,因为虽然允许只附加一个事件处理程序而不是n,但它不允许您附加事件的stopPropagation()