简体   繁体   English

在带有点击事件的li中,停止选中复选框两次

[英]Stop checkbox being checked twice when inside an li with a click event

I'm writing a simple dropdown menu with jQuery and each item has a checkbox. 我正在用jQuery写一个简单的下拉菜单,每个项目都有一个复选框。 When I click on an li element the checkbox is selected. 当我单击li元素时,该复选框已选中。 However if I click on the checkbox itself, it does not select because it is effectively checked twice. 但是,如果我单击复选框本身,则不会选中该复选框,因为它已被有效地选中了两次。 How can I stop this happening? 我该如何阻止这种情况发生?

jsFiddle: http://jsfiddle.net/ZEp7V/ jsFiddle: http : //jsfiddle.net/ZEp7V/

HTML: HTML:

<div id="dropdown">Channels</div>
<ul class="droplist">
    <li>News <input type="checkbox" /></li>
    <li>Sport <input type="checkbox" /></li>
    <li>Science <input type="checkbox" /></li>
    <li>Health <input type="checkbox" /></li>
    <li>All</li>
</ul>

CSS: CSS:

div#dropdown {
    border: 1px solid #000;
    width: 150px;
    height: 20px;
    line-height: 20px;
    padding: 10px;
    cursor: pointer;
}

ul.droplist {
    display: none;
    width: 170px;
    border: 1px solid #000;
    border-bottom: none;
    list-style-type: none;
    padding: 0px;
    margin: 0px;
    position: absolute;
    background-color: #fff;
}

ul.droplist li {
    border-bottom: 1px solid #000;
    padding: 10px;
    cursor: pointer;
}

ul.droplist li input {
    float: right;
}

JS: JS:

$(document).ready(function(){

    $("#dropdown").click(function() {
        $(this).next().slideToggle(200);
    });

    $(".droplist li").click(function(e) {
        // Toggle the checkbox
        var input = $(this).children("input");
        $(input).prop("checked", !$(input).prop("checked"));
    });

    $(".droplist li:last").click(function () {
        // Select all boxes
        var check = $('.droplist li input:not(:checked)').length;
        $(".droplist li input").prop("checked", check);
    });

});

You can stop the propagation of the event at the checkbox: 您可以在复选框中停止传播事件:

$(".droplist li :checkbox").click(function (e) {
    e.stopPropagation();
});

This will prevent the event from bubbling up the DOM tree to the parent li element (where, as you say, it triggers the event handler bound to it). 这将防止事件将DOM树冒泡到父li元素(如您所说,在此触发绑定到它的事件处理程序)。


As a side note, you could modify your code to take advantange of event delegation, which is more efficient since there's only one event handler instead of one for each li element. 附带说明一下,您可以修改代码以采用事件委托的优势,因为只有一个事件处理程序,而不是每个li元素一个,所以效率更高。 For example: 例如:

$(".droplist").on("click", "li", function (e) {
    // Toggle the checkbox
    var input = $(this).children("input");
    $(input).prop("checked", !$(input).prop("checked"));
});

See the .on() method for more details. 有关更多详细信息,请参见.on()方法。

Wrap the checkboxes with labels (labels share the browser native click event with the input) 用标签包裹复选框(标签与输入共享浏览器本机点击事件)

<li><label for="news_input">News <input type="checkbox" id="news_input" /></label></li>
<li><label for="sport_input">Sport <input type="checkbox" id="sport_input" /></li>
<li><label for="science_input">Science <input type="checkbox" id="science_input" /></li>
<li><label for="health_input">Health <input type="checkbox" id="health_input" /></li>

And get rid of this behaviour 并摆脱这种行为

$(".droplist li").click(function(e) {
   // Toggle the checkbox
  var input = $(this).children("input");
  $(input).prop("checked", !$(input).prop("checked"));
});

Like this, you should be fine. 这样,你应该没事。 The problem with your solution is that the native browser checkbox function and jQuery kill each other as soon as a user hits the input with a click. 您的解决方案的问题在于,当用户单击单击输入时,本机浏览器复选框功能和jQuery会互相杀死。 (Browser checks the checkbox, jQuery unchecks it) (浏览器选中该复选框,jQuery取消选中该复选框)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM