没有 jQuery 的下拉菜单中的手风琴?

Accordion inside Dropdown without jQuery?

我想在我的下拉菜单中添加手风琴。但是,当单击 open/close 的手风琴时,整个下拉列表会崩溃。相反,我希望下拉菜单保持打开状态,手风琴可以自由 open/close。

Check out a demo here

<div class="btn-group dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
    Dropdown
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenu2">
    <button class="dropdown-item" type="button">Action</button>
    <button class="dropdown-item" type="button">Another action</button>
    <button class="dropdown-item" type="button">Something else here</button>

    <div id="accordion">
      <div class="card">
        <div class="card-header" id="headingOne">
          <h5 class="mb-0">
            <button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
              Collapsible Test
            </button>
          </h5>
        </div>
        <div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
          <div class="card-body">
            <button class="dropdown-item" type="button">Test</button>
          </div>
        </div>
      </div>
    </div>

  </div>
</div>

似乎有很多类似的问题,但我找不到正确的解决方案。很多答案建议使用 jQuery 来解决这个问题。有没有办法做到这一点?

我相信使用 data-boundarydata-parent 可能是执行此操作的方法,但我不知道如何做。

您可以通过向按钮添加一个 onclick 事件来防止点击向下传播到下拉列表来实现此目的。然后你需要手动处理添加相关的 collapsecollapse.show 类 到 onclick 函数中的手风琴内容,如下所示:

function toggleAccordion(event) {
  event.stopPropagation();
  var collapsable = document.getElementById('collapseOne');
  var classList = collapsable.classList;
  if(classList.contains('collapse')) {
    classList.replace('collapse', 'collapse.show');
  } else if (classList.contains('collapse.show')) {
    classList.replace('collapse.show', 'collapse');
  }
}

和添加了点击事件的HTML:

<div class="btn-group dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
    Dropdown
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenu2">
    <button class="dropdown-item" type="button">Action</button>
    <button class="dropdown-item" type="button">Another action</button>
    <button class="dropdown-item" type="button">Something else here</button>

    <div id="accordion">
      <div class="card">
        <div class="card-header" id="headingOne">
          <h5 class="mb-0">
            <button type="button" class="btn btn-link" onclick="toggleAccordion(event)">
              Collapsible Test
            </button>
          </h5>
        </div>
        <div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
          <div class="card-body">
            <button class="dropdown-item" type="button">Test</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

我修改了你的 JSFiddle 来展示一个有效的解决方案,你可以找到它 here。另一个注意事项,我必须将 JS 加载类型更改为 No wrap - bottom of <head/body> 才能使其工作。

虽然@Jake 给出了有效的答案,但我发现了某种 "hack" 可以让这项工作无需编写任何额外的 JS。

只需用 form 标签替换手风琴 div

<div class="btn-group dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown">
    Dropdown
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenu2">
    <button class="dropdown-item" type="button">Action</button>
    <button class="dropdown-item" type="button">Another action</button>
    <button class="dropdown-item" type="button">Something else here</button>

    <form id="accordion">

        <div  id="headingOne">
          <h5 class="mb-0">
            <button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
              Collapsible Test
            </button>
          </h5>
        </div>
        <div id="collapseOne" class="collapse" data-parent="#accordion">
          <div class="card-body">
            <button class="dropdown-item" type="button">Test</button>
          </div>
        </div>

    </form>

  </div>
</div>

不幸的是,我不知道为什么会这样,所以我无法在答案中给出原因。