简体   繁体   English

为什么复选框的“checked”属性返回与click事件的实际值相反的值?

[英]Why does a checkbox's “checked” attribute return the opposite of it's actual value on click event?

I've got the following HTML 我有以下HTML

<li><input type="checkbox" /><label>This is the label!</label></li>

I bound a click event to the li, and let the click event bubble up to the li before doing anything else. 我将点击事件绑定到li,并在执行任何其他操作之前让click事件冒泡到li。

$('li').each(function(i){
  var item = $(this);
  var checkbox = $("input[type='checkbox']", item);

  item.bind('click', function(e){
    var isChecked = checkbox.is(':checked');
    console.log(isChecked);
    e.stopPropagation();
  });
});

Starting with an unchecked checkbox, when the click event fires, isChecked returns true when I click on the checkbox, but returns false when I click on the label or li. 从未选中的复选框开始,当click事件触发时,isChecked在我单击复选框时返回true,但是当我单击标签或li时返回false。 Does anyone know why? 有谁知道为什么?

[EDIT:] To demonstrate the issue, have a look at this http://jsfiddle.net/nYbf6/2/ . [编辑:]为了证明这个问题,请看看这个http://jsfiddle.net/nYbf6/2/

  1. Click on the checkbox in the first li. 单击第一个li中的复选框。
  2. Click inside the second li, but not on a label or checkbox. 单击第二个li内部,但不在标签或复选框上。

Notice that you can never toggle the checkbox by clicking on the checkbox because the 'checked' attribute always returns what it is not when clicking on the checkbox. 请注意,您永远不能通过单击复选框切换复选框,因为“checked”属性始终返回单击复选框时不存在的内容。

[EDIT:] Found the answer here today: http://www.bennadel.com/blog/1525-jQuery-s-Event-Triggering-Order-Of-Default-Behavior-And-triggerHandler-.htm . [编辑:]今天在这里找到答案: http//www.bennadel.com/blog/1525-jQuery-s-Event-Triggering-Order-Of-Default-Behavior-And-triggerHandler-.htm I'm not fond of the solution, but it's better than no solution. 我不喜欢这个解决方案,但它比没有解决方案更好。

the click event of a checkbox fires before the value is changed. 复选框的click事件在值更改之前触发。 This way, if you return false when you override the click event, it stops the checkbox from changing it's value. 这样,如果在覆盖click事件时返回false,则会阻止复选框更改其值。 You should change the event to fire onclick of the checkbox, not the li that contains it. 您应该更改事件以激活复选框,而不是包含它的li。

You would do better to fetch the appropriate checkbox as part of the click , like this: 你会做的更好,以获取相应的复选框作为的一部分click ,如下所示:

$('li').click(function(e) {
  var isChecked = $(':checkbox:checked', this).length > 0;
  console.log(isChecked);
  e.stopPropagation();
});

This finds the checkbox in the <li> that was clicked when it was clicked. 这会在单击<li>时找到单击时单击的复选框。

As for the why part, if you're clicking on the checkbox, you're setting it to true, then the event propagates to the li which determines the checkbox is indeed checked. 至于为什么部分,如果你点击复选框,你将其设置为true,然后事件传播到li ,确定复选框确实已检查。 With an unchecked box if you're clicking on the label, it's not checking the box, so it's still false. 如果您点击标签时未使用框,则不会选中该框,因此它仍然是错误的。 If you checked the box then clicked the label, you'll see true coming back, because now it's checked. 如果您选中了该框, 单击该标签,您将看到true回来,因为现在已经检查过了。

If you're expecting the label to check the checkbox, you need to relate it using label's for attribute, like this: 如果你期待的标签,选中该复选框,则需要使用标签对涉及它for属性,就像这样:

<li>
  <input id="myInput" type="checkbox" />
  <label for="myInput">This is the label!</label>
</li>

Then the browser will handle the connection, click the label will toggle the checkbox. 然后浏览器将处理连接,单击标签将切换复选框。

Try this: 试试这个:

<li>
  <input type='checkbox' value='foo' id='myFavoriteCheckbox'>
  <label for='myFavoriteCheckbox'>The Label</label>
</li>

Now when you click on the label, the checkbox will be affected. 现在,当您单击标签时,复选框将受到影响。 Bind the handler to the checkbox and check .attr('checked') and you'll find that even on click events the value of the checkbox will be correct. 将处理程序绑定到复选框并检查.attr('checked') ,您会发现即使在click事件上,复选框的值也是正确的。 Note also that that's true even if you decide to stop propagation and prevent default for the event. 另请注意, 即使您决定停止传播并阻止事件的默认设置 ,也是如此。 In other words, if you handle a click event and decide to prevent the default action, your handler will still see the value of "checked" set to what it would be if you did not stop the default action. 换句话说,如果您处理click事件并决定阻止默认操作,则处理程序仍会看到“已检查”的值设置为停止默认操作时的值。

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

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