我对 :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/