javascript - :not() to filter out elements in event handler 的用法

原文 标签 javascript jquery css-selectors

我对 :not() selector 感到很困惑.在普通的 CSS 中似乎相当简单:

section { /* Overriden as expected */
  color: red;
}
input {
  color: green; /* In effect as expected */
}
:not(input) {
  color: blue; /* In effect as expected */
}
<section>
  <p>Lorem ipsum</p>
  <input value="Lorem ipsum">
</section>


但是,当应用于过滤触发事件的选定元素的后代时,我无法掌握逻辑:

jQuery(function($){
  $(document).on("keydown", "input", function(event){
    // This fires only for <input> as expected
    console.log("Event handler #1 on", event.target);
  });  

  $(document).on("keydown", ":not(input)", function(event){
    // This fires for *all* elements :-?
    console.log("Event handler #2 on", event.target);
    // ... even though these checks return the results that intuition suggests
    console.log('Is "input"? %s; Is ":not(input)"? %s',
      $(event.target).is("input"),
      $(event.target).is(":not(input)")
    );
  });

  $(document).on("keydown", "section :not(input)", function(event){
    // This *never* fires :-?
    console.log("Event handler #3 on", event.target);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <p>Click and type here</p>
  <input value="Click and type here">
</section>


背后的原理是什么:not()在这里工作?

我真的在寻找解释而不是修复。

最佳答案

问题在于keydown事件从 input 冒泡.如果您使用 :not(input) ,当事件刚刚在 input 处初始化时,处理程序不会触发。元素,但它会在事件冒泡到 section 时触发元素。您可以通过检查 this 来检查这一点。在函数内部,它将引用处理程序触发时事件冒泡到的元素。 (当您在输入字段中输入时,event.target 将始终是 input)

jQuery(function($){
  $(document).on("keydown", ":not(input)", function(event){
    // This fires for *all* elements :-?
    console.log("Event handler #2 on", this);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <p>Click and type here</p>
  <input value="Click and type here">
</section>


如果继续添加 :not s,你会看到它一直冒泡到 HTML 标签:

jQuery(function($){
  $(document).on("keydown", ":not(input):not(section):not(body)", function(event){
    // This fires for *all* elements :-?
    console.log("Event handler #2 on", this);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <p>Click and type here</p>
  <input value="Click and type here">
</section>


我想你可以使用 :not(input):not(section):not(body):not(html) ,但这有点愚蠢且难以管理。

您的第三个处理程序正确地排除了 input从触发事件,但只有 input (和类似的)元素火 keydown事件 - 它不能从 <section> 触发, 例如。如果有 section 的 textarea 子项可能会更清楚以及输入 - 您会看到 textarea 触发处理程序,但输入不会:

$(document).on("keydown", "section :not(input)", function(event) {
  console.log("Event handler #3 on", event.target);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <p>Click and type here</p>
  <input value="Click and type here">
  <textarea></textarea>
</section>

关于javascript - :not() to filter out elements in event handler 的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53757749/

相关文章:

CSS 性能 : descendent or two direct descendent selectors best?

javascript - react native -从数组中删除对象

javascript - 在javascript下拉菜单中自动生成年份

javascript - 是什么导致JavaScript函数无法运行它的回调

javascript - 只是尝试检查该值是否存在于数组中

html - 如何使用 :not selector with :nth-of-type

javascript - 如何解决Bootstrap中的“样式表无法加载”

javascript - 正则表达式模式来替换和禁用href链接

jquery - getScript停止工作

html - CSS同级(〜)选择器对选中的属性无效