Bootstrap下拉菜单以及可点击的父容器中的其他按钮

时间:2019-09-05 15:47:29

标签: javascript jquery twitter-bootstrap

我正在尝试在另一个可点击的父级中添加bootstrap下拉菜单。我猜这有点棘手。这是我创建的Codepen,并重新创建了问题。

Codepen with the issue recreated

预期的行为:单击下拉列表时,将触发该下拉列表,因此单击另一个按钮(如果过于棘手,则可以选择),并且没有一个会触发对父级的单击。

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

 $('.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');
});

1 个答案:

答案 0 :(得分:1)

首先,最好在目标处过滤事件,而不要调用stopPropagation。如果停止事件的传播,它将阻止任何其他全局侦听器捕获它们。例如,如果停止点击事件传播,则其他下拉列表将不会关闭。

因此,我改为引入了这种整洁的过滤器方法,该方法可让您检查事件的源或其父级是否具有一个类:

/**
 * 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;
}

不幸的是,您仍然需要stopPropagation作为按钮,否则click事件将立即关闭下拉菜单。

第二,您要呼叫.dropdown("toggle")

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

所有的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');
});

您想将no-orange放在不应更改背景颜色的元素上:

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

所有一起在这里:https://codepen.io/MXXIV/pen/rNBpepd