【问题标题】:Working Dropdown menu in the newest version of Bootstrap? [duplicate]在最新版本的 Bootstrap 中工作的下拉菜单? [复制]
【发布时间】:2021-09-04 04:52:18
【问题描述】:

我正在开发一个需要下拉菜单中的下拉菜单的网站,但显然在 bootstrap 5.0 中他们删除了该功能?听说还有办法获取子菜单,但是我试过的所有方法都不起作用,请帮忙!

【问题讨论】:

    标签: html css twitter-bootstrap bootstrap-5


    【解决方案1】:

    这是实现它的简洁方式!

    (function($bs) {
            const CLASS_NAME = 'has-child-dropdown-show';
        $bs.Dropdown.prototype.toggle = function(_orginal) {
            return function() {
                document.querySelectorAll('.' + CLASS_NAME).forEach(function(e) {
                    e.classList.remove(CLASS_NAME);
                });
                let dd = this._element.closest('.dropdown').parentNode.closest('.dropdown');
                for (; dd && dd !== document; dd = dd.parentNode.closest('.dropdown')) {
                    dd.classList.add(CLASS_NAME);
                }
                return _orginal.call(this);
            }
        }($bs.Dropdown.prototype.toggle);
    
        document.querySelectorAll('.dropdown').forEach(function(dd) {
            dd.addEventListener('hide.bs.dropdown', function(e) {
                if (this.classList.contains(CLASS_NAME)) {
                    this.classList.remove(CLASS_NAME);
                    e.preventDefault();
                }
                if(e.clickEvent && e.clickEvent.composedPath().some(el=>el.classList && el.classList.contains('dropdown-toggle'))){
                    e.preventDefault();
                }
                e.stopPropagation(); // do not need pop in multi level mode
            });
        });
    
        // for hover
        function getDropdown(element) {
            return $bs.Dropdown.getInstance(element) || new $bs.Dropdown(element);
        }
    
        document.querySelectorAll('.dropdown-hover, .dropdown-hover-all .dropdown').forEach(function(dd) {
            dd.addEventListener('mouseenter', function(e) {
                let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
                if (!toggle.classList.contains('show')) {
                    getDropdown(toggle).toggle();
                }
            });
            dd.addEventListener('mouseleave', function(e) {
                let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
                if (toggle.classList.contains('show')) {
                    getDropdown(toggle).toggle();
                }
            });
        });
    })(bootstrap);
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no" />
        <!-- Begin SEO tag -->
        <title>Infinite Multiple Level Dropdown Menu base on Bootstrap</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
        <style>.dropdown-hover-all .dropdown-menu, .dropdown-hover > .dropdown-menu.dropend { margin-left:-1px !important }</style>
    </head>
    
    <body class="">
        <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
            <div class="collapse navbar-collapse" id="navbarsExampleDefault">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Demo <span class="sr-only">(current)</span></a>
                    </li>
                    <li class="nav-item dropdown dropdown-hover">
                        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Hover</a>
                        <div class="dropdown-menu" aria-labelledby="dropdown01">
                            <a class="dropdown-item" href="#">Single App</a>
                            <a class="dropdown-item" href="#">Multiple Works</a>
                            <div class="dropdown-divider"></div>
                            <a class="dropdown-item" href="#">Disctribution</a>
                        </div>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" id="dropdown02" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Documents</a>
                        <div class="dropdown-menu" aria-labelledby="dropdown02">
                            <a class="dropdown-item" href="#">Introduction</a>
                            <div class="dropdown dropend">
                                <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Layouts</a>
                                <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                                    <a class="dropdown-item" href="#">Basic</a>
                                    <a class="dropdown-item" href="#">Compact Aside</a>
                                    <div class="dropdown-divider"></div>
                                    <div class="dropdown dropend">
                                        <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Custom</a>
                                        <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                                            <a class="dropdown-item" href="#">Fullscreen</a>
                                            <a class="dropdown-item" href="#">Empty</a>
                                            <div class="dropdown-divider"></div>
                                            <a class="dropdown-item" href="#">Magic</a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="dropdown-divider"></div>
                            <a class="dropdown-item" href="#">Something else here</a>
                        </div>
                    </li>
                    <li class="nav-item active">
                        <a class="nav-link" href="https://github.com/dallaslu/bootstrap-5-multi-level-dropdown">View on Github</a>
                    </li>
                </ul>
            </div>
        </nav>
        <div class="container" style="padding-top: 3.5rem">
            <div class="dropdown mt-3">
                <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-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>
                    <div class="dropdown dropend">
                        <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Layouts</a>
                        <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                            <a class="dropdown-item" href="#">Basic</a>
                            <a class="dropdown-item" href="#">Compact Aside</a>
                            <div class="dropdown-divider"></div>
                            <div class="dropdown dropend">
                                <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Custom</a>
                                <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                                    <a class="dropdown-item" href="#">Fullscreen</a>
                                    <a class="dropdown-item" href="#">Empty</a>
                                    <div class="dropdown-divider"></div>
                                    <a class="dropdown-item" href="#">Magic</a>
                                </div>
                            </div>
                        </div>
                    </div>
                    <a class="dropdown-item" href="#">Something else here</a>
                </div>
            </div>
            <div class="d-flex dropdown-hover-all">
              <div class="dropdown mt-3">
                  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton222" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                      Dropdown Hover
                  </button>
                  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton222">
                      <a class="dropdown-item" href="#">Action</a>
                      <div class="dropdown dropend">
                          <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Layouts</a>
                          <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                              <a class="dropdown-item" href="#">Basic</a>
                              <a class="dropdown-item" href="#">Compact Aside</a>
                              <div class="dropdown-divider"></div>
                              <div class="dropdown dropend">
                                  <a class="dropdown-item dropdown-toggle" href="#" id="dropdown-layouts" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Custom</a>
                                  <div class="dropdown-menu" aria-labelledby="dropdown-layouts">
                                      <a class="dropdown-item" href="#">Fullscreen</a>
                                      <a class="dropdown-item" href="#">Empty</a>
                                      <div class="dropdown-divider"></div>
                                      <a class="dropdown-item" href="#">Magic</a>
                                  </div>
                              </div>
                          </div>
                      </div>
                      <a class="dropdown-item" href="#">Something else here</a>
                  </div>
                </div>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.min.js" integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc" crossorigin="anonymous"></script>
    
    </body>
    
    </html>

    另外,请记住,hover 功能不适用于移动设备。现在您可以为自己选择最佳方案!

    【讨论】:

      【解决方案2】:

      这里是获取菜单下子菜单的代码。

      HTML:

      >  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
      >     <div class="container-fluid">
      >     <a class="navbar-brand" href="#">Brand</a>
      >     <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main_nav" 
      > aria-expanded="false" aria-label="Toggle navigation">
      >     <span class="navbar-toggler-icon"></span>
      >     </button>
      >     <div class="collapse navbar-collapse" id="main_nav">
      >       <ul class="navbar-nav">
      >         <li class="nav-item active"> <a class="nav-link" href="#">Home </a> </li>
      >         <li class="nav-item"><a class="nav-link" href="#"> About </a></li>
      >         <li class="nav-item dropdown" id="myDropdown">
      >           <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">  Treeview menu  </a>
      >           <ul class="dropdown-menu">
      >             <li> <a class="dropdown-item" href="#"> Dropdown item 1 </a></li>
      >             <li> <a class="dropdown-item" href="#"> Dropdown item 2 &raquo; </a>
      >               <ul class="submenu dropdown-menu">
      >                 <li><a class="dropdown-item" href="#">Submenu item 1</a></li>
      >                 <li><a class="dropdown-item" href="#">Submenu item 2</a></li>
      >                 <li><a class="dropdown-item" href="#">Submenu item 3 &raquo; </a>
      >                   <ul class="submenu dropdown-menu">
      >                     <li><a class="dropdown-item" href="#">Multi level 1</a></li>
      >                     <li><a class="dropdown-item" href="#">Multi level 2</a></li>
      >                   </ul>
      >                 </li>
      >                 <li><a class="dropdown-item" href="#">Submenu item 4</a></li>
      >                 <li><a class="dropdown-item" href="#">Submenu item 5</a></li>
      >               </ul>
      >             </li>
      >             <li><a class="dropdown-item" href="#"> Dropdown item 3 </a></li>
      >             <li><a class="dropdown-item" href="#"> Dropdown item 4 </a></li>
      >           </ul>
      >         </li>
      >       </ul>
      >     </div>
      >     <!-- navbar-collapse.// -->
      >     </div>
      >     <!-- container-fluid.// -->
      >     </nav>
      

      JavaScript:

      document.addEventListener("DOMContentLoaded", function(){
      // make it as accordion for smaller screens
      if (window.innerWidth < 992) {
      
        // close all inner dropdowns when parent is closed
        document.querySelectorAll('.navbar .dropdown').forEach(function(everydropdown){
          everydropdown.addEventListener('hidden.bs.dropdown', function () {
            // after dropdown is hidden, then find all submenus
              this.querySelectorAll('.submenu').forEach(function(everysubmenu){
                // hide every submenu as well
                everysubmenu.style.display = 'none';
              });
          })
        });
      
        document.querySelectorAll('.dropdown-menu a').forEach(function(element){
          element.addEventListener('click', function (e) {
              let nextEl = this.nextElementSibling;
              if(nextEl && nextEl.classList.contains('submenu')) {    
                // prevent opening link if link needs to open dropdown
                e.preventDefault();
                if(nextEl.style.display == 'block'){
                  nextEl.style.display = 'none';
                } else {
                  nextEl.style.display = 'block';
                }
      
              }
          });
        })
      }
      // end if innerWidth
      }); 
      // DOMContentLoaded  end
      

      用于响应的 CSS:

      /* ============ desktop view ============ */
      @media all and (min-width: 992px) {
          .dropdown-menu li{ position: relative;  }
          .nav-item .submenu{ 
              display: none;
              position: absolute;
              left:100%; top:-7px;
          }
          .nav-item .submenu-left{ 
              right:100%; left:auto;
          }
          .dropdown-menu > li:hover{ background-color: #f1f1f1 }
          .dropdown-menu > li:hover > .submenu{ display: block; }
      }   
      /* ============ desktop view .end// ============ */
      
      /* ============ small devices ============ */
      @media (max-width: 991px) {
        .dropdown-menu .dropdown-menu{
            margin-left:0.7rem; margin-right:0.7rem; margin-bottom: .5rem;
        }
      }   
      /* ============ small devices .end// ============ */
      

      输出:

      【讨论】:

      • 您分享的答案适用于桌面屏幕。但是,当您在移动屏幕上使用它时,子菜单将不起作用,因为您共享了基于悬停的子菜单。
      猜你喜欢
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多