首页 > 解决方案 > 复选框在自行选择时不起作用

问题描述

我有一张桌子,每一行都有一个复选框。

<table id="myTable">
<tr>
    <td>
       <input type="checkbox" class="checkbox">
    </td>
    <td>
       content
    </td>
</tr>
... more rows
</table>

我想选中/取消选中复选框并在单击一行时更改类。这很好用,但是,当我单击复选框本身时,什么也没有发生。从字面上看,甚至无法选中/取消选中。

$(document).on("click", "#myTable tr", function() {
        var ths = $(this),
            chk = ths.find(".checkbox");

        if (chk.is(":checked")) {
            ths.removeClass("success");
            chk.prop("checked", false);
        } else {
            ths.addClass("success");
            chk.prop("checked", true);
        }
    });

不太确定我错过了什么。

标签: jquery

解决方案


单击复选框时,该事件会冒泡到 TR 并切换两次 - 因为 TR 单击会这样做。

解决方案:

由于停止事件传播通常是一个草率的想法1,您可以改为 检测谁是第一个接收事件的元素 ( Event.target) - 并采取相应的行动:

$("#myTable").on("click", "tr", function(evt) {

  var $tr = $(this),
      chk = $tr.find(".checkbox")[0]; // ! Not a jQuery Object, but a JS Element
  
  // If checkbox was NOT the direct Event.target
  if (chk !== evt.target) {
    chk.checked = !chk.checked; // toggle artificially the checkbox state
  }
  
  // Do the following on whoever was the Event.target
  $tr.toggleClass("success", chk.checked);

});
.success { background: #0bf; }
<table id="myTable">
  <tr>
    <td>
      <input type="checkbox" class="checkbox">
    </td>
    <td>
      content
    </td>
  </tr>
</table>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

注意 if#myTable 附加到当前或未来 tr元素 的事件的静态delegateTarget处理程序$("#myTable"),而不是使用而不是$(document)作为静态选择器。


1争论为什么使用Event.target优于: 取 ie: 一个元素,如饥似渴地等待事件触发通知,或关闭打开模式,但从未注册它 - 导致用户界面损坏。Event.stopPropagation()
<body>


推荐阅读