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

时间:2010-04-01 22:58:15

标签: javascript jquery javascript-events onclick

我有以下HTML

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

我将点击事件绑定到li,并在执行任何其他操作之前让点击事件冒泡到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();
  });
});

从未选中的复选框开始,当click事件触发时,isChecked在我单击复选框时返回true,但在单击标签或li时返回false。有谁知道为什么?

[编辑:] 要演示此问题,请查看此http://jsfiddle.net/nYbf6/2/

  1. 点击第一个li中的复选框。
  2. 在第二个li中单击,但不在标签或复选框上。
  3. 请注意,您永远不能通过单击复选框来切换复选框,因为“已检查”属性始终会返回单击复选框时未显示的内容。

    [编辑:] 今天在这里找到答案:http://www.bennadel.com/blog/1525-jQuery-s-Event-Triggering-Order-Of-Default-Behavior-And-triggerHandler-.htm。我不喜欢这个解决方案,但它比没有解决方案更好。

3 个答案:

答案 0 :(得分:2)

复选框的click事件会在更改值之前触发。这样,如果在覆盖click事件时返回false,则会阻止复选框更改其值。您应该更改事件以激活复选框,而不是包含它的li。

答案 1 :(得分:1)

您最好在click中获取相应的复选框,如下所示:

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

这会找到<li>中单击时单击的复选框。

至于为什么部分,如果您点击复选框,则将其设置为true,然后事件传播到li,这确定复选框确实是检查。如果您点击标签时未使用框,则不会选中该框,因此它仍然是错误的。如果您选中框然后点击了标签,您会看到true回来,因为现在已经检查过了。

如果您希望标签选中复选框,则需要使用标签的for属性将其关联,如下所示:

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

然后浏览器将处理连接,单击标签将切换复选框。

答案 2 :(得分:1)

试试这个:

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

现在,当您点击标签时,该复选框将受到影响。将处理程序绑定到复选框并检查.attr('checked'),您会发现即使在click事件中,复选框的值也是正确的。另请注意,即使您决定停止传播并阻止事件的默认,这也是真的。换句话说,如果您处理click事件并决定阻止默认操作,您的处理程序将仍然看到“已检查”的值设置为您执行的操作< em> not 停止默认操作。