我很难理解为什么单击标签时无法停止传播。
<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()
,复选框功能仍会被触发。这个问题看似简单,但是解决方案似乎要少得多……
答案 0 :(得分:2)
发生这种情况是因为这是浏览器的默认行为。您可以通过以下两种方式将复选框与标签相关联:
复选框:
for
或使用<label for="box">Test</label><input type="checkbox" id="box"/>
属性,例如:
label
在两种情况下,都将在单击标签时自动选中/取消选中该复选框。 w3.org中也提到了这一点。
因此,为了防止执行此默认操作,您应该在$(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");
}
单击内使用event.preventDefault()
,例如:
<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>
属性,例如:
{{1}}
答案 1 :(得分:1)
这对我有用
$('#box').on('change',function(e){
console.log(e);
});
答案 2 :(得分:1)
您需要停止click
(由用户)在label
上的传播,然后触发click
(由浏览器)在input
上的传播。因此,您只需要停止该事件的传播即可。然后剩下的就是change
上的input
事件,从而导致期望的行为。
(仍然有点烦人,我知道...)
在下面的代码段中,请注意单击标签与单击复选框之间的区别!
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;
});