: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()
在这里工作的原理是什么?
我实际上是在寻找一种解释,而不是一种解决方法。
答案 0 :(得分:5)
问题是keydown
事件从input
起起泡。如果您使用:not(input)
,则事件仅在input
元素上初始化时,处理程序将不会触发,但是当事件起泡到{{1 }}元素。您可以通过检查函数内部的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>
,则会看到它一直冒到HTML标签:
:not
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>
的textarea子项以及输入-您会看到textarea触发了处理程序,但是输入却没有:
section
$(document).on("keydown", "section :not(input)", function(event) {
console.log("Event handler #3 on", event.target);
});