停止标签上的单击事件传播



我很难理解为什么当我点击标签时无法停止传播。

<label for="box">
<input type="checkbox" id="box" />
Test
</label>
$(function() {
$('#box').on('click', checkbox);
$('label').on('click', label);
});
function label(e) {
console.log('label');
e.stopPropagation();
}
function checkbox(e) {
console.log('checkbox');
e.stopPropagation();
}

当我单击标签时,尽管标签函数中有stopPropagation(),复选框函数仍会被激活。这是一个看起来很简单的问题,但解决方案似乎不那么简单…

之所以会发生这种情况,是因为这是浏览器的默认行为。您可以通过两种方式将复选框与标签关联起来:

  1. 标签内的复选框,如:

    <label><input type="checkbox" id="box"/>Test</label>
    
  2. 或者使用for属性,如:

    <label for="box">Test</label><input type="checkbox" id="box"/>
    

在这两种情况下,单击标签时都会自动检查/取消检查复选框。w3.org.中也提到了这一点

因此,为了防止这种默认操作,您应该在label点击中使用event.preventDefault(),如:

$(function() {
$('#box').on('click', checkbox);
$('label').on('click', label);
})
function label(e) {
e.preventDefault();
console.log('label');  
}
function checkbox(e) {
e.stopPropagation();
console.log("checkbox");  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="box">
<input type="checkbox" id="box"/>Test
</label>

如果您正在寻找一个更简单的解决方案,那么您可以将标签和复选框分离,并从标签中删除for属性,如:

<div class="wrapper">  
<input type="checkbox" id="box"/>&nbsp;
<label>Test</label>
</div>

这对我来说是工作

$('#box').on('change',function(e){
console.log(e);
});

您需要停止click(由用户(在label上的传播,然后在input上触发click(由浏览器(。所以您只需要停止该事件的传播。那么剩下的就是CCD_ 11上的CCD_。

(还是有点烦人,我知道…(

在下面的片段中,请注意单击标签与单击复选框之间的区别!

let input = document.getElementById('box');
let label = document.getElementById('boxLabel');
// Stop user click from propagating
label.addEventListener('click', stopProp);
// Stop browser click from propagating
input.addEventListener('click', stopProp);
function stopProp(e) {
e.stopPropagation();
console.log(e.target + ' Click stopped!');
}
input.addEventListener('change', function(e) {
console.log(e.target + ' Value changed!');
});
<label id="boxLabel" for="box">
<input type="checkbox" id="box"/>
Test
</label>

或者,如果您不想在输入:上点击事件

选项A:设置标志

let flag_ignoreNextClick = false;
label.addEventListener('click', function() {
flag_ignoreNextClick = true;
});
input.addEventListener('click', function() {
if(flag_ignoreNextClick) {
// Consume flag
flag_ignoreNextClick = false;
return;
}
//TODO do 'only on checkbox click' stuff here...
});

选项B:模拟切换

label.addEventListener('click', function(e) {
// Prevent input click event
e.preventDefault();
// Emulate toggle
input.checked ^= true;
});

我也遇到了同样的问题。使用

event.preventDefault();

在标签内的物品上,做了手脚

最新更新