SO 上也提出了与此类似的问题,但他们要么只关心解决其具体实现,要么没有明确提出这个问题。此外,所有答案都没有真正解决这个问题。
给出以下示例:
document.querySelector('span').addEventListener('click', function(event) {
event.stopPropagation();
});
<label>
<input type='checkbox'/>
<span>Click Me!</span>
</label>
为什么这不足以防止单击跨度时检查复选框?
相反,有必要调用event.preventDefault()
以防止标签选中(或取消选中)复选框。这似乎违反直觉。在此示例中,这意味着单击跨度本身会导致复选框切换,而不是单击然后冒泡到标签。
This is not very well specified and is actually platform specific (even though all major platforms/vendors combinations seem to act similarly here). specs https://html.spec.whatwg.org/multipage/forms.html#the-label-element - temp link https://html.spec.whatwg.org/multipage/forms.html#the-label-element:the-label-element-10
[标签元素的]激活行为可能是什么(如果有的话)应该与平台的标签行为相匹配
标签事实上的默认行为是将点击分派到其链接的<input>
元素(“标记控件”),可能来自遗留预激活行为 https://dom.spec.whatwg.org/#eventtarget-legacy-pre-activation-behavior,在事件通过其路径实际分派之前触发(步骤 12here https://dom.spec.whatwg.org/#dispatching-events, 临时链接 https://dom.spec.whatwg.org/#ref-for-eventtarget-legacy-pre-activation-behavior%E2%91%A0).
因此,即使事件的传播在捕获阶段停止在文档层(DOM 中的第一个目标),触发事件的默认行为new click
事件于<input>
将会发生:
let block_at_capture = false;
const span = document.querySelector("span");
const label = document.querySelector("label");
const input = document.querySelector("input");
span.onclick = (evt) => {
console.log("clicked the span");
};
input.onclick = (evt) => {
console.log("clicked the input");
};
label.addEventListener( "click", (evt) => {
console.log("clicked the label in capturing phase");
}, true );
label.addEventListener( "click", (evt) => {
console.log("clicked the label in bubbling phase");
}, false );
document.addEventListener( "click", (evt) => {
if( evt.target !== span ) { return; }
if( block_at_capture ) {
console.log("blocking at document capture");
evt.stopPropagation();
}
block_at_capture = !block_at_capture;
}, true );
<input id="inp" type="checkbox">
<label for="inp"><span>click me</span></label>
也就是说,除非默认行为被阻止或链接在分派事件时被破坏......
请注意,即使没有<label>
:
// The click event won't get called
document.querySelector("input").onclick = (evt) =>
console.log("clicked on input");
// even though the default behavior ("change") will still happen
document.querySelector("input").onchange = (evt) =>
console.log("changed input"); // will get called
document.addEventListener("click",
(evt) => evt.stopPropagation(),
true
);
<input type="checkbox">
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)