带有显示和隐藏事件的 Bootstrap 3 嵌套可折叠元素

max*_*max 4 javascript jquery twitter-bootstrap

我正在使用 Bootstrap 折叠来创建第三级菜单。我正在向panel-active父级添加类moreless在 CSS 中更改为。问题是,当我打开时Item 2.1panel-active类被添加到#test3(这是好的)AND #test2(这是坏的)。当我打开/隐藏时,Bootstrapshown.bs.collapsehidden.bs.collapse事件似乎触发了两次,我Item 2.1不知道为什么会这样。

要重现该问题,请尝试隐藏Item 2.1.

$('.panel-collapse').on('shown.bs.collapse', function() {
  $(this).parent().addClass('panel-active');
});

$('.panel-collapse').on('hidden.bs.collapse', function() {
  $(this).parent().removeClass('panel-active');
});
Run Code Online (Sandbox Code Playgroud)
.container {
  margin-top: 50px;
}
.list-group-item.panel {
  margin-bottom: 0;
}
.sidebar-submenu {
  padding: 0;
  list-style: none;
}
.sidebar-submenu a {
  padding-left: 30px !important;
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
  display: block;
}
.sidebar-submenu .sidebar-submenu a {
  padding-left: 60px !important;
}
.list-group a[data-toggle] {
  position: relative;
}
.list-group-item > a[data-toggle]:after,
.sidebar-submenu-item > a[data-toggle]:after
{
  content: 'more';
  position: absolute;
  right: 10px;
  top: 6px;
  color: #333;
  z-index: 438
}
.panel-active > a[data-toggle]:after {
  content: 'less'
 }
.list-group .list-group-item a {
  padding: 13px 12px;
  display: block;
  border-bottom: 1px solid #eee;
}
.list-group .list-group-item {
  padding: 0;
}
Run Code Online (Sandbox Code Playgroud)
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<div class="container">
  <div class="row">
    <div class="col-md-4">
      <ul class="list-group" id="sidebar-menu">

        <li class="list-group-item panel panel-default">
          <a href="#test1" data-toggle="collapse" data-parent="#sidebar-menu" class="collapsed"><i class="fa fa-check fa-fw icon-left"></i>Item 1</a>
          <div class="panel-collapse collapse" id="test1">
            <ul class="sidebar-submenu">
              <li class="sidebar-submenu-item"><a href="#">Item 1.1</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 1.2</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 1.3</a>
              </li>
            </ul>
          </div>
        </li>
        <li class="list-group-item panel panel-default">
          <a href="#test2" data-toggle="collapse" data-parent="#sidebar-menu" class="collapsed"><i class="fa fa-check fa-fw icon-left"></i>Item 2</a>
          <div class="panel-collapse collapse" id="test2">
            <ul class="sidebar-submenu">
              <li class="sidebar-submenu-item">
                <a href="#test3" data-toggle="collapse" class="collapsed">Item 2.1</a>
                <div class="panel-collapse collapse" id="test3">
                  <ul class="sidebar-submenu">
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.1</a>
                    </li>
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.2</a>
                    </li>
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.3</a>
                    </li>
                  </ul>
                </div>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 2.2</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 2.3</a>
              </li>
            </ul>
          </div>
        </li>

      </ul>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

mah*_*man 5

当您点击一个子元素时,您也同时点击了父元素,因此父元素和子元素的两个事件都会触发。要仅触发子事件并阻止它向上传播 dom 树,请添加e.stopPropagation()如下内容。

$('.panel-collapse').on('shown.bs.collapse', function(e) {
  e.stopPropagation();
  $(this).parent().addClass('panel-active');
});

$('.panel-collapse').on('hidden.bs.collapse', function(e) {
  e.stopPropagation();
  $(this).parent().removeClass('panel-active');
});
Run Code Online (Sandbox Code Playgroud)
.container {
  margin-top: 50px;
}
.list-group-item.panel {
  margin-bottom: 0;
}
.sidebar-submenu {
  padding: 0;
  list-style: none;
}
.sidebar-submenu a {
  padding-left: 30px !important;
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
  display: block;
}
.sidebar-submenu .sidebar-submenu a {
  padding-left: 60px !important;
}
.list-group a[data-toggle] {
  position: relative;
}
.list-group-item > a[data-toggle]:after,
.sidebar-submenu-item > a[data-toggle]:after
{
  content: 'more';
  position: absolute;
  right: 10px;
  top: 6px;
  color: #333;
  z-index: 438
}
.panel-active > a[data-toggle]:after {
  content: 'less'
 }
.list-group .list-group-item a {
  padding: 13px 12px;
  display: block;
  border-bottom: 1px solid #eee;
}
.list-group .list-group-item {
  padding: 0;
}
Run Code Online (Sandbox Code Playgroud)
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<div class="container">
  <div class="row">
    <div class="col-md-4">
      <ul class="list-group" id="sidebar-menu">

        <li class="list-group-item panel panel-default">
          <a href="#test1" data-toggle="collapse" data-parent="#sidebar-menu" class="collapsed"><i class="fa fa-check fa-fw icon-left"></i>Item 1</a>
          <div class="panel-collapse collapse" id="test1">
            <ul class="sidebar-submenu">
              <li class="sidebar-submenu-item"><a href="#">Item 1.1</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 1.2</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 1.3</a>
              </li>
            </ul>
          </div>
        </li>
        <li class="list-group-item panel panel-default">
          <a href="#test2" data-toggle="collapse" data-parent="#sidebar-menu" class="collapsed"><i class="fa fa-check fa-fw icon-left"></i>Item 2</a>
          <div class="panel-collapse collapse" id="test2">
            <ul class="sidebar-submenu">
              <li class="sidebar-submenu-item">
                <a href="#test3" data-toggle="collapse" class="collapsed">Item 2.1</a>
                <div class="panel-collapse collapse" id="test3">
                  <ul class="sidebar-submenu">
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.1</a>
                    </li>
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.2</a>
                    </li>
                    <li class="sidebar-submenu-item"><a href="#">Item 2.1.3</a>
                    </li>
                  </ul>
                </div>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 2.2</a>
              </li>
              <li class="sidebar-submenu-item"><a href="#">Item 2.3</a>
              </li>
            </ul>
          </div>
        </li>

      </ul>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)