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

时间:2020-04-17 13:59:53

标签: jquery events click stoppropagation

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

<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(),复选框功能仍会被触发。这个问题看似简单,但是解决方案似乎要少得多……

3 个答案:

答案 0 :(得分:2)

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

    标签中的
  1. 复选框:

    for
  2. 或使用<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"/>&nbsp; <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;
});