简体   繁体   English

使用可点击父容器内的其他按钮的Bootstrap下拉列表

[英]Bootstrap dropdown with other button inside clickable parent container

I am trying to add a bootstrap dropdown inside another clickable parent. 我试图在另一个可点击的父项中添加一个bootstrap下拉列表。 It's kind of tricky I guess. 我觉得这有点棘手。 Here is the Codepen I created with the issue recreated. 这是我在重新创建问题时创建的Codepen。

Codepen with the issue recreated Codepen重新创建了问题

Expected behavior: On clicking the dropdown, the dropdown will fire, so will by clicking the other button (optional if too tricky) and none will trigger a click on the parent. 预期的行为:在单击下拉列表时,下拉列表将会触发,因此将单击其他按钮(如果太棘手则可选),并且不会触发父项单击。

    <div class="card-body parent" style="min-height: 300px;">
      <!-- ORIGINAL DROPPER BUTTON -->
      <div class="dropdown original-dropper mb-5">
        <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown button
        </button>
        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
        </div>
      </div>

      <!-- OTHER DROPPER BUTTON -->
      <button class="btn btn-danger other-dropper mt-5 d-inline">Other Button</button>
    </div>

JS: JS:

 $('.parent').on('click', function(e) {
  $(this).css('backgroundColor', 'darkorange');
});

$('.other-dropper').on('click', function(e) {
  e.stopPropagation();
  $('.original-dropper .dropdown-toggle').dropdown();
  console.log('clicked');
});

First, it's better to filter an event at the target instead of calling stopPropagation . 首先,最好在目标上过滤事件而不是调用stopPropagation If you stop propagation of event, it prevents any other global listeners from capturing them. 如果停止传播事件,则会阻止任何其他全局侦听器捕获它们。 For example, other dropdowns will not close if click event propagation was stopped. 例如,如果单击事件传播已停止,则其他下拉列表将不会关闭。

So instead I introduced this neat filter method, that allows you to check if the source of event or it's parents has a class: 所以我引入了这个简洁的过滤方法,它允许你检查事件源或它的父母是否有一个类:

/**
 * Checks if any of parent nodes of elm has a class name
 * @param {HTMLElement} elm the starting node
 * @param {string} className
 * @param {HTMLElement} stopAtElm if this parent is reached, search stops
**/
function treeHasClass(elm, className, stopAtElm) {
  while(elm != null && elm != stopAtElm) {
    if(elm.classList.contains(className)) {
      return true;
    }
    elm = elm.parentNode;
  }
  return false;
}

Unfortunately you still need stopPropagation for the button, else the click event would close the drop-down immediately. 不幸的是,你仍然需要对按钮进行stopPropagation ,否则click事件会立即关闭下拉列表。

Second, you want to call .dropdown("toggle") : 其次,你想调用.dropdown("toggle")

$('.original-dropper .dropdown-toggle').dropdown("toggle");

All together, the javascript is: 总之,javascript是:

$('.parent').on('click', function(e) {
  // Do not trigger if target elm or it's child has `no-orange` class
  if(!treeHasClass(e.target, "no-orange", this)) {
    $(this).css('backgroundColor', 'darkorange');
  }
});

$('.other-dropper').on('click', function(e) {
  e.stopPropagation();
  e.preventDefault();
  $('.original-dropper .dropdown-toggle').dropdown("toggle");
  console.log('clicked');
});

And you want to put no-orange to elements that shouldn't change background color: 并且您希望将no-orange放在不应更改背景颜色的元素上:

<button class="no-orange btn btn-danger other-dropper mt-5 d-inline">Other Button</button>

All together here: https://codepen.io/MXXIV/pen/rNBpepd 在这里一起: https//codepen.io/MXXIV/pen/rNBpepd

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

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