停止父元素onclick传播但允许下拉打开/关闭和Bootstrap下拉菜单项事件?

时间:2016-09-13 20:32:53

标签: twitter-bootstrap drop-down-menu datatables event-propagation

我有一个jQuery DataTables表,其中包含select选项(单击时会选中行)。我遇到的问题是点击下拉按钮和下拉菜单项会导致选择基础行。 如何阻止基础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>

我也尝试手动切换下拉列表,但是这个引入了奇怪的下拉行为(例如,点击一行的下拉菜单显示了其下拉菜单,但没有隐藏任何其他行&#39 ;已经打开的下拉菜单:

<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>

1 个答案:

答案 0 :(得分:0)

事实证明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>