我很难理解为什么当我点击标签时无法停止传播。
<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()
,复选框函数仍会被激活。这是一个看起来很简单的问题,但解决方案似乎不那么简单…
之所以会发生这种情况,是因为这是浏览器的默认行为。您可以通过两种方式将复选框与标签关联起来:
-
标签内的复选框,如:
<label><input type="checkbox" id="box"/>Test</label>
-
或者使用
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"/>
<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();
在标签内的物品上,做了手脚