停止父元素的 onclick 传播但允许下拉菜单 open/close 和 Bootstrap 下拉菜单的菜单项事件?

Stop parent element onclick propagation but allow dropdown open/close and menu item events for Bootstrap dropdown?

我有一个带有 select 选项的 jQuery DataTables table(单击时选择行)。我遇到的问题是单击下拉按钮和下拉菜单项导致选择基础行。 我怎样才能防止底层的 td/tr/DataTable select 单击事件,但允许 dropdown 及其菜单项(li a 子项) 点击事件?

<table id="datatable">
  <tr>
    <td>
      <div class="dropdown">
        <button type="button" class="dropdown-toggle" data-toggle="dropdown">
          <i class="fa fa-caret-down"></i>
        </button>
        <ul class="dropdown-menu">
          <li><a href="#" class="action">Action</a></li>
        </ul>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="dropdown">
        <button type="button" class="dropdown-toggle" data-toggle="dropdown">
          <i class="fa fa-caret-down"></i>
        </button>
        <ul class="dropdown-menu">
          <li><a href="#" class="action">Action</a></li>
        </ul>
      </div>
    </td>
  </tr>
</table>

<script>
  $("#datatable").DataTable({ select: true });
</script>

我试过使用 e.stopPropagation() 但这 阻止了下拉菜单显示 :

<script>
  $("#dataTable tbody").on("click", "button", function (e) {
    e.stopPropagation(); // this prevents dropdown menu from showing
  });
</script>

我也尝试过手动切换下拉菜单,但这 引入了奇怪的下拉行为(例如,单击一行的下拉按钮显示其下拉菜单,但没有隐藏任何其他行'已打开的下拉菜单):

<script>
  $("#dataTable tbody").on("click", "button", function (e) {
    $(this).closest("div.dropdown").toggleClass("open"); // weird effects
    // or:
    $(this).closest("div.dropdown").find("ul.dropdown-menu").toggle(); // weird effects

    e.stopPropagation();
  });
</script>

我也尝试了 dropdown("toggle"),但是虽然这解决了上述奇怪的行为,但它仍然 阻止了菜单项的点击事件 :

<script>
  $("#dataTable tbody").on("click", "button", function (e) {
    // no weird behavior, but now menu item click events are disabled
    $(this).closest("div.dropdown").find("ul.dropdown-menu").dropdown("toggle");

    e.stopPropagation();
  });
</script>

原来 jQuery DataTables 为这种情况提供了事件处理程序 user-select.dt。我能够获得正常工作所需的所有功能:

<script>
  $("#datatable").DataTable({
    select: true
  }).on("user-select.dt", function (e, dt, type, cell, originalEvent) {
    var $elem = $(originalEvent.target); // get element clicked on
    var tag = $elem[0].nodeName.toLowerCase(); // get element's tag name

    if (!$elem.closest("div.dropdown").length) {
      return; // ignore any element not in the dropdown
    }

    if (tag === "i" || tag === "a" || tag === "button") {
      return false; // cancel the select event for the row
    }
  });
</script>