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 的子文本区域可能会更清楚以及输入 - 你会看到文本区域触发处理程序,但输入不会:

$(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/

相关文章:

javascript - Ajax 调用不断被浏览器阻止

JQuery DataTables .Net 服务器端分页问题

css - 如何为菜单的具体部分(字母)着色?

javascript - 如何正确转义 css/js 属性选择器 [attr=value] 中的属性值?

javascript - 查询 :focus when the browser ain't focused

javascript - 带有反应路由器的菜单组件未渲染

javascript - 为什么我的动态添加的边框在 IE8 中不显示?

javascript - 使用嵌入式 PDF 检测 iframe 中的鼠标和键盘事件

javascript - JQuery .load 中的 Bootstrap 下拉列表无法正常工作

css - 使用我的 CSS 定位 Woocommerce 订单接收页面