【问题标题】:How to implement a Navbar Dropdown Hover in Bootstrap v4?如何在 Bootstrap v4 中实现导航栏下拉悬停?
【发布时间】:2017-06-30 05:38:55
【问题描述】:

我对新的引导程序版本有点困惑,因为他们将下拉菜单更改为 div:

<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">Navbar</a>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Features</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Pricing</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown link
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
    </ul>
  </div>
</nav>

你们有什么想法可以在该 sn-p 的下拉链接中获得悬停下拉菜单,而无需添加额外的脚本代码(仅来自引导程序的 css 和脚本)?我已经看到了 bootstrap css 类,但我无法与 bootstrap V3 中的类关联(我在 V3 中没有添加 jquery 就完成了这个)。

【问题讨论】:

  • 我遇到了类似的问题并想出了这个解决方案stackoverflow.com/questions/47357143/…
  • 悬停菜单是个坏主意,而且如果您计划使用移动设备,这也是一个糟糕的 UI/UX

标签: html css twitter-bootstrap


【解决方案1】:

我正在使用 bootstrap 5,上面的解决方案看起来很大,我刚刚删除了 data-bs-toggle='dropdown'因为它阻止了父链接导航和切换脚本以在点击时打开下拉列表。

并添加了 CSS

.dropdown:hover > .dropdown-menu {
    display: block;
    margin-top: 0;
    // removes the gap so it doesn't close ;
}

适合我

【讨论】:

    【解决方案2】:

    只需使用 Tao 的 CSS 代码:

    .dropdown:hover > .dropdown-menu {
       display: block;
    }
    

    并通过将 .dropdown-toggle 和 .dropdown-menu 的上边距设置为零来移除 .dropdown-toggle 和 .dropdown-menu 之间的 2px 间隙:

    .dropdown-menu { margin-top: 0!important }
    

    【讨论】:

      【解决方案3】:

      我在这里找不到完整的解决方案。所以,这是我的一个与 Bootstrap v4.4.1 一起使用并具有下一个好处

      • 点击dropdown-toggle 就像一个普通的导航链接。

      • 支持任何嵌套级别的下拉菜单。

      • Bootstrap 4 {show/shown/hide/hidden}.bs.dropdown 事件运行良好。

         // Toggles a B4 dropdown-menu to a given state.
         const toggleDropdownElement = ($dropdown, shouldOpen = false) => {
           const $dropdownToggle = $dropdown.children('[data-toggle="dropdown"], a');
           const $dropdownMenu = $dropdown.children('.dropdown-menu');
        
           // Change the dropdown menu. It's similar to B4 Dropdown.show()/.hide(), see /bootstrap/js/src/dropdown.js.
           if (shouldOpen) {
             $dropdown.trigger('show.bs.dropdown');
             $dropdownToggle.attr('aria-expanded', true).focus();
             $dropdownMenu.addClass('show');
             $dropdown.addClass('show').trigger($.Event('shown.bs.dropdown', $dropdownMenu[0]));
           } else {
             $dropdown.trigger('hide.bs.dropdown');
             $dropdownToggle.attr('aria-expanded', false);
             $dropdownMenu.removeClass('show');
             $dropdown.removeClass('show').trigger($.Event('hidden.bs.dropdown', $dropdownMenu[0]));
           }
         };
        
         // Toggles a B4 dropdown-menu with any nesting level.
         const toggleDropdown = (event) => {
           const $dropdown = $(event.target).closest('.dropdown');
           const $parentDropdownMenu = $dropdown.closest('.dropdown-menu');
           const shouldOpen = event.type !== 'click' && $dropdown.is(':hover');
        
           // If the dropdown was closed already, break the 'mouseleave' event cascade.
           if (!shouldOpen && !$dropdown.hasClass('show')) return;
        
           // Change the current dropdown menu (last nested).
           toggleDropdownElement($dropdown, shouldOpen);
        
           // We have to close the dropdown menu tree if it was a click or the menu was leave at all.
           if (event.type === 'click' || $parentDropdownMenu.length && !$parentDropdownMenu.is(':hover')) {
             $dropdown.parents('.dropdown').each((index, element) => {
               toggleDropdownElement($(element), false);
             });
           }
         };
        
         if (viewport && viewport.is('>=xl')) {
           $('body')
             .on('mouseenter mouseleave', '.dropdown', toggleDropdown)
             .on('click', '.dropdown-menu a', toggleDropdown);
        
           // Disable the default B4's click. Other words, change a dropdown-toggle to a normal nav link.
           $(document).off('click.bs.dropdown', '[data-toggle="dropdown"]');
           $(document).off('click.bs.dropdown.data-api', '[data-toggle="dropdown"]'); // Not sure about it.
         }
        

      如果您不使用 ES6,只需将箭头函数更改为旧的函数样式即可。

      谢谢@tao 你的例子,这对我很有帮助。

      代码相关链接:B4 Dropdown Eventsviewport (Responsive Bootstrap Toolkit)WP Bootstrap Navwalker

      【讨论】:

        【解决方案4】:

        Google 把我带到了这里,但是......如果下拉菜单在显示时与其父级重叠(至少 1 像素),则提供的示例有效。如果没有,它就会失去焦点,并且没有任何效果。

        这是一个使用 jQuery 和 Bootstrap 4.5.2 的有效解决方案:

        $('li.nav-item').mouseenter(function (e) {
        
                e.stopImmediatePropagation();
        
                if ($(this).hasClass('dropdown')) {
        
                    // target element containing dropdowns, show it
                    $(this).addClass('show');
                    $(this).find('.dropdown-menu').addClass('show');
        
                    // Close dropdown on mouseleave
                    $('.dropdown-menu').mouseleave(function (e) {
                        e.stopImmediatePropagation();
                        $(this).removeClass('show');
                    });
        
                    // If you have a prenav above, this clears open dropdowns (since you probably will hover the nav-item going up and it will reopen its dropdown otherwise)
                    $('#prenav').off().mouseenter(function (e) {
                        e.stopImmediatePropagation();
                        $('.dropdown-menu').removeClass('show');
                    });
        
                } else {
                    // unset open dropdowns if hover is on simple nav element
                    $('.dropdown-menu').removeClass('show');
                }
            });
        

        【讨论】:

          【解决方案5】:

          (2020 年 6 月)我找到了这个解决方案,我想我应该把它贴在这里:

          引导版本:4.3.1

          CSS 部分:

          .navbar .nav-item:not(:last-child) {
            margin-right: 35px;
          }
          
          .dropdown-toggle::after {
             transition: transform 0.15s linear;
          }
          
          .show.dropdown .dropdown-toggle::after {
            transform: translateY(3px);
          }
          
          .dropdown-menu {
            margin-top: 0;
          }
          

          jQuery部分:

          const $dropdown = $(".dropdown");
          const $dropdownToggle = $(".dropdown-toggle");
          const $dropdownMenu = $(".dropdown-menu");
          const showClass = "show";
          
          $(window).on("load resize", function() {
            if (this.matchMedia("(min-width: 768px)").matches) {
              $dropdown.hover(
                function() {
                  const $this = $(this);
                  $this.addClass(showClass);
                  $this.find($dropdownToggle).attr("aria-expanded", "true");
                  $this.children($dropdownMenu).addClass(showClass);
                },
                function() {
                  const $this = $(this);
                  $this.removeClass(showClass);
                  $this.find($dropdownToggle).attr("aria-expanded", "false");
                  $this.children($dropdownMenu).removeClass(showClass);
                }
              );
            } else {
              $dropdown.off("mouseenter mouseleave");
            }
          });
          

          来源:https://webdesign.tutsplus.com/tutorials/how-to-make-the-bootstrap-navbar-dropdown-work-on-hover--cms-33840

          【讨论】:

            【解决方案6】:

            这两种顶级解决方案都不适合我。

            这很好用,在浏览时保持子菜单打开,添加使用本机 Bootstrap javascript。

            // Mouse over
            $('body').on('mouseover', '.dropdown', function(e) { 
                $(this).children('.dropdown-toggle').dropdown('show');
            });
            
            // Mouse leave
            $('body').on('mouseleave', '.dropdown', function(e) { 
                $(this).children('.dropdown-toggle').dropdown('hide');
            });
            

            【讨论】:

              【解决方案7】:

              仅 CSS 和桌面解决方案

              @media (min-width: 992px) { 
              .dropdown:hover>.dropdown-menu {
                display: block;
              }
              }
              

              【讨论】:

                【解决方案8】:

                1.移除 data-toggle="dropdown" 属性(所以点击不会打开下拉菜单)

                2。添加 :hover 伪类以显示下拉菜单

                .dropdown:hover .dropdown-menu {display: block;}
                <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
                <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
                <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
                <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
                
                <nav class="navbar navbar-toggleable-md navbar-light bg-faded">
                  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                  </button>
                  <a class="navbar-brand" href="#">Navbar</a>
                  <div class="collapse navbar-collapse" id="navbarNavDropdown">
                    <ul class="navbar-nav">
                      <li class="nav-item active">
                        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
                      </li>
                      <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" aria-haspopup="true" aria-expanded="false">
                          Dropdown link
                        </a>
                        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                          <a class="dropdown-item" href="#">Action</a>
                          <a class="dropdown-item" href="#">Another action</a>
                          <a class="dropdown-item" href="#">Something else here</a>
                        </div>
                      </li>
                      <li class="nav-item">
                        <a class="nav-link" href="#">Features</a>
                      </li>
                      <li class="nav-item">
                        <a class="nav-link" href="#">Pricing</a>
                      </li>
                    </ul>
                  </div>
                </nav>

                【讨论】:

                  【解决方案9】:

                  $('body').on('mouseenter mouseleave','.dropdown',function(e){
                    var _d=$(e.target).closest('.dropdown');
                    if (e.type === 'mouseenter')_d.addClass('show');
                    setTimeout(function(){
                      _d.toggleClass('show', _d.is(':hover'));
                      $('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
                    },300);
                  });
                  
                  /* this is not needed, just prevents page reload when a dd link is clicked */
                  $('.dropdown a').on('click tap', e => e.preventDefault())
                  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
                  <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
                  <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
                  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
                  
                  <nav class="navbar navbar-toggleable-md navbar-light bg-faded">
                    <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                      <span class="navbar-toggler-icon"></span>
                    </button>
                    <a class="navbar-brand" href>Navbar</a>
                    <div class="collapse navbar-collapse" id="navbarNavDropdown">
                      <ul class="navbar-nav">
                        <li class="nav-item active">
                          <a class="nav-link" href>Home <span class="sr-only">(current)</span></a>
                        </li>
                        <li class="nav-item">
                          <a class="nav-link" href>Features</a>
                        </li>
                        <li class="nav-item">
                          <a class="nav-link" href>Pricing</a>
                        </li>
                        <li class="nav-item dropdown">
                          <a class="nav-link dropdown-toggle" href id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            Dropdown link
                          </a>
                          <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                            <a class="dropdown-item" href>Action</a>
                            <a class="dropdown-item" href>Another action</a>
                            <a class="dropdown-item" href>Something else here</a>
                          </div>
                        </li>
                      </ul>
                    </div>
                  </nav>

                  【讨论】:

                    【解决方案10】:

                    可悬停下拉菜单,而不会丢失 popper.js 的功能,仅适用于 bootstrap 4

                    Javascript

                    $('.dropdown-hoverable').hover(function(){
                        $(this).children('[data-toggle="dropdown"]').click();
                    }, function(){
                        $(this).children('[data-toggle="dropdown"]').click();
                    });
                    

                    HTML

                    <nav class="nav">
                      <li class="nav-item dropdown dropdown-hoverable">
                        <a class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#">Menu link</a>
                        <ul class="dropdown-menu">
                        </ul>
                      </li>
                    </nav>
                    

                    【讨论】:

                      【解决方案11】:

                      我使用引导程序 4.0.0 因为我们要模拟.show 来悬停事件,所以很简单。只需将.dropdown.show .dropdown-menu 中的所有样式添加到:hover。像这样:

                      .dropdown:hover>.dropdown-menu {
                        opacity: 1;
                        visibility: visible;
                        transform: translate3d(0px, 0px, 0px);
                      }
                      

                      【讨论】:

                        【解决方案12】:

                        简单,仅 CSS 解决方案:

                        .dropdown:hover>.dropdown-menu {
                          display: block;
                        }
                        

                        单击时,它仍会切换到 show 类(当不再悬停时将保持打开状态)。


                        要绕过这个适当地是使用为基于指针的设备保留的事件和属性:jQuery 的mouseentermouseleave:hover。应该能够流畅、直观地工作,同时完全不会干扰下拉菜单在基于触摸的设备上的工作方式。试试看,让我知道它是否适合你:

                        完整的 jQuery 解决方案touch 原封不动):

                        Pre v4.1.2 解决方案(已弃用):

                        $('body').on('mouseenter mouseleave','.dropdown',function(e){
                          var _d=$(e.target).closest('.dropdown');
                          if (e.type === 'mouseenter')_d.addClass('show');
                          setTimeout(function(){
                            _d.toggleClass('show', _d.is(':hover'));
                            $('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
                          },300);
                        });
                        

                        $('body').on('mouseenter mouseleave','.dropdown',function(e){
                          var _d=$(e.target).closest('.dropdown');
                          if (e.type === 'mouseenter')_d.addClass('show');
                          setTimeout(function(){
                            _d.toggleClass('show', _d.is(':hover'));
                            $('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
                          },300);
                        });
                        
                        /* this is not needed, just prevents page reload when a dd link is clicked */
                        $('.dropdown a').on('click tap', e => e.preventDefault())
                        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
                        <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
                        <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
                        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
                        
                        <nav class="navbar navbar-toggleable-md navbar-light bg-faded">
                          <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                            <span class="navbar-toggler-icon"></span>
                          </button>
                          <a class="navbar-brand" href>Navbar</a>
                          <div class="collapse navbar-collapse" id="navbarNavDropdown">
                            <ul class="navbar-nav">
                              <li class="nav-item active">
                                <a class="nav-link" href>Home <span class="sr-only">(current)</span></a>
                              </li>
                              <li class="nav-item">
                                <a class="nav-link" href>Features</a>
                              </li>
                              <li class="nav-item">
                                <a class="nav-link" href>Pricing</a>
                              </li>
                              <li class="nav-item dropdown">
                                <a class="nav-link dropdown-toggle" href id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                  Dropdown link
                                </a>
                                <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                                  <a class="dropdown-item" href>Action</a>
                                  <a class="dropdown-item" href>Another action</a>
                                  <a class="dropdown-item" href>Something else here</a>
                                </div>
                              </li>
                            </ul>
                          </div>
                        </nav>

                        v4.1.2 shiplistthis change 介绍了下拉菜单的工作原理,使上述解决方案不再有效。
                        以下是 最新 解决方案,用于在 v4.1.2 及更高版本中悬停时打开下拉菜单:

                        function toggleDropdown (e) {
                          const _d = $(e.target).closest('.dropdown'),
                            _m = $('.dropdown-menu', _d);
                          setTimeout(function(){
                            const shouldOpen = e.type !== 'click' && _d.is(':hover');
                            _m.toggleClass('show', shouldOpen);
                            _d.toggleClass('show', shouldOpen);
                            $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
                          }, e.type === 'mouseleave' ? 300 : 0);
                        }
                        
                        $('body')
                          .on('mouseenter mouseleave','.dropdown',toggleDropdown)
                          .on('click', '.dropdown-menu a', toggleDropdown);
                        

                        function toggleDropdown (e) {
                          const _d = $(e.target).closest('.dropdown'),
                              _m = $('.dropdown-menu', _d);
                          setTimeout(function(){
                            const shouldOpen = e.type !== 'click' && _d.is(':hover');
                            _m.toggleClass('show', shouldOpen);
                            _d.toggleClass('show', shouldOpen);
                            $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
                          }, e.type === 'mouseleave' ? 300 : 0);
                        }
                        
                        $('body')
                          .on('mouseenter mouseleave','.dropdown',toggleDropdown)
                          .on('click', '.dropdown-menu a', toggleDropdown);
                        
                        /* not needed, prevents page reload for SO example on menu link clicked */
                        $('.dropdown a').on('click tap', e => e.preventDefault())
                        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
                        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
                        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
                        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
                        
                        <nav class="navbar navbar-expand-lg navbar-light bg-light">
                          <a class="navbar-brand" href="#">Navbar</a>
                          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                            <span class="navbar-toggler-icon"></span>
                          </button>
                        
                          <div class="collapse navbar-collapse" id="navbarSupportedContent">
                            <ul class="navbar-nav mr-auto">
                              <li class="nav-item active">
                                <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
                              </li>
                              <li class="nav-item">
                                <a class="nav-link" href="#">Link</a>
                              </li>
                              <li class="nav-item dropdown">
                                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                  Dropdown
                                </a>
                                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                                  <a class="dropdown-item" href="#">Action</a>
                                  <a class="dropdown-item" href="#">Another action</a>
                                  <div class="dropdown-divider"></div>
                                  <a class="dropdown-item" href="#">Something else here</a>
                                </div>
                              </li>
                              <li class="nav-item">
                                <a class="nav-link disabled" href="#">Disabled</a>
                              </li>
                            </ul>
                            <form class="form-inline my-2 my-lg-0">
                              <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
                              <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
                            </form>
                          </div>
                        </nav>

                        重要提示:如果使用 jQuery 解决方案,删除 CSS 很重要(否则单击 .dropdown-toggle 或单击菜单选项时下拉菜单不会关闭)。

                        【讨论】:

                        • 您好,感谢您的回答,我也完成了,但是如果您单击下拉菜单“停留”。我不想使用“preventdefault”之类的东西,你知道一些 css 技巧(删除或添加)来让下拉菜单不停留在点击上吗?
                        • @Exprove 没有 clean CSS 方法可以做到这一点。因为 Bootstrap 使用的是JavaSript。没有js,引导下拉菜单不起作用。无论如何,我花时间研究了他们是如何做到的,我想出了一个脚本,它不涉及 touch 行为,并提供了您在桌面上所要求的内容。测试一下,如果您发现任何问题,请告诉我,到目前为止,我没有。如果需要,愿意改进它。如果处理得当,可能会对许多人派上用场。
                        • 一切正常,但我真的需要让下拉链接工作,如果我按下“下拉链接”它应该转到example.com,我就是无法做到这一点,我已经有了一个接近的解决方案(就像你的 jquery 一样)。也许如果我用 jquery 覆盖点击事件可能会起作用,但这似乎是一个草率的解决方案。
                        • 使用split button。它们正是为此而生的。
                        • 添加这个修复了上述解决方案中的差距。.dropdown>.dropdown-menu { margin: 0; }
                        【解决方案13】:

                        CSS 解决方案在触控设备上无法正常工作

                        我发现任何 CSS 解决方案都可以让菜单在触摸设备上保持打开状态,它们不再折叠。

                        所以我读了这篇文章:https://www.brianshim.com/webtricks/drop-down-menus-on-ios-and-android/ (by Brian Shim)
                        很有用!它指出触摸设备总是首先检查元素上是否存在悬停类。

                        但是:通过使用 jQuery .show(),您引入了一个样式属性 (display:block;),它使菜单在第一次触摸时打开。现在菜单已经打开,没有引导程序“显示”类。如果用户从下拉菜单中选择一个链接,它会完美运行。但是,如果用户决定关闭菜单而不使用它,他必须点击两次才能关闭菜单:在第一次点击时,原始引导程序“显示”类被附加,因此菜单再次打开,在第二次点击时,菜单关闭到正常的引导行为(删除“显示”类)。

                        为了防止这种情况,我使用了这篇文章:https://codeburst.io/the-only-way-to-detect-touch-with-javascript-7791a3346685(David Gilbertson)

                        他有一些非常方便的方法来检测触摸或悬停设备。

                        所以,将两位作者与我自己的一点 jQuery 结合起来:

                        $(window).one('mouseover', function(){
                              window.USER_CAN_HOVER = true;
                              if(USER_CAN_HOVER){
                                  jQuery('#navbarNavDropdown ul li.dropdown').on("mouseover", function() {
                                     var $parent = jQuery(this);
                                     var $dropdown = $parent.children('ul');
                        
                                     $dropdown.show(200,function() { 
                                       $parent.mouseleave(function() {
                                         var $this = jQuery(this);
                                         $this.children('ul').fadeOut(200);
                                       });
                                     });
                                  });
                              };
                        

                        }); 检查一次设备是否允许悬停事件。如果是这样,请引入使用 .show() 悬停的可能性。如果设备不允许悬停事件,则 .show() 永远不会被引入,因此您可以在触摸设备上获得自然的引导行为。

                        请务必删除任何有关菜单悬停类的 CSS。

                        花了我三天时间 :) 所以我希望它对你们中的一些人有所帮助。

                        【讨论】:

                          【解决方案14】:

                          Andrei 的“完整”jQuery+CSS 解决方案具有正确的意图,但它很冗长且仍然不完整。不完整,因为虽然它可能涵盖了所有必要的 DOM 更改,但它缺少custom events 的触发。冗长,因为当 Bootstrap 已经提供了 dropdown() method 时,它正在重新发明,它可以做所有事情。

                          因此,正确的 DRY 解决方案(不依赖于其他答案中经常重复的 CSS hack)是只是 jQuery

                          $('body').on('mouseover mouseout', '.dropdown', function(e) {
                              $(e.target).dropdown('toggle');
                          });
                          

                          【讨论】:

                          • 我倾向于在鼠标事件上远离toggles。如果它只失火一次,则下拉菜单将在未悬停时保持打开状态,并在悬停时隐藏。通常,通过在元素上涂写光标,可能会误触发进入/离开指针序列。但是为了正确测试,悬停元素,更改选项卡或窗口,然后将鼠标放在另一个位置并返回到您的窗口。现在悬停元素。
                          • 上面描述的pureCSS解决方案比这个更准确。
                          • @AndreiGheorghiu 哎呀,我选择的鼠标事件不是最好的; mouseover mouseout 似乎解决了这个问题。谢谢,我会编辑我的帖子。
                          • @MohammadAyoubKhan 纯 CSS 解决方案会遗漏各种其他行为,包括触发事件以及切换某些类和属性。
                          • 为我工作!如果您遇到错误,请像这样try { $(e.target).dropdown('toggle'); } catch(z) { /* just to hide the error */ } 压制它们
                          【解决方案15】:

                          Bootstrap 4 仅 CSS

                          没有一个 CSS only 答案完全有效。点击后下拉菜单保持打开状态,或者在您到达要点击的菜单链接之前,下拉菜单会隐藏起来。

                          这里是简单的纯 CSS 解决方案:

                          .navbar-nav li:hover .dropdown-menu {
                              display: block;
                          }
                          

                          从 HTML 标记中删除 data-toggle=dropdown 以防止下拉菜单在点击时保持打开状态。使用mt-0 (margin-top:0) 消除菜单上方的间隙,并使悬停菜单项成为可能。

                          演示https://www.codeply.com/go/awyU7VTIJf


                          完整代码:

                             .navbar-nav li:hover .dropdown-menu {
                                  display: block;
                              } 
                          
                             <nav class="navbar navbar-expand-lg navbar-light bg-light">
                                ..
                                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                                  <ul class="navbar-nav mr-auto">
                                    <li class="nav-item dropdown">
                                      <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown">
                                        Dropdown
                                      </a>
                                      <div class="dropdown-menu mt-0" aria-labelledby="navbarDropdown">
                                        <a class="dropdown-item" href="#">Action</a>
                                        <a class="dropdown-item" href="#">Another action</a>
                                        <div class="dropdown-divider"></div>
                                        <a class="dropdown-item" href="#">Something else here</a>
                                      </div>
                                    </li>
                                  </ul>
                                </div>
                              </nav>   
                          

                          【讨论】:

                          • mt-0 小费是金子。我的下拉菜单有时会消失,有时不会。
                          【解决方案16】:

                          Bootstrap v4 解决方案 - 基于 jQuery,但比纯 css 解决方案更好

                          这确保您仍然可以关注顶级链接点击,并且是 兼容手机。

                          在构建时考虑了桌面和移动设备。随意用一个检查窗口宽度是否大于 768px 的条件来包装 jQuery。

                          jQuery

                          /** Dropdown on hover */
                          $(".nav-link.dropdown-toggle").hover( function () {
                              // Open up the dropdown
                              $(this).removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link
                              $(this).parent().addClass('show'); // add the class show to the li parent
                              $(this).next().addClass('show'); // add the class show to the dropdown div sibling
                          }, function () {
                              // on mouseout check to see if hovering over the dropdown or the link still
                              var isDropdownHovered = $(this).next().filter(":hover").length; // check the dropdown for hover - returns true of false
                              var isThisHovered = $(this).filter(":hover").length;  // check the top level item for hover
                              if(isDropdownHovered || isThisHovered) {
                                  // still hovering over the link or the dropdown
                              } else {
                                  // no longer hovering over either - lets remove the 'show' classes
                                  $(this).attr('data-toggle', 'dropdown'); // put back the data-toggle attr
                                  $(this).parent().removeClass('show');
                                  $(this).next().removeClass('show');
                              }
                          });
                          // Check the dropdown on hover
                          $(".dropdown-menu").hover( function () {
                          }, function() {
                              var isDropdownHovered = $(this).prev().filter(":hover").length; // check the dropdown for hover - returns true of false
                              var isThisHovered= $(this).filter(":hover").length;  // check the top level item for hover
                              if(isDropdownHovered || isThisHovered) {
                                  // do nothing - hovering over the dropdown of the top level link
                              } else {
                                  // get rid of the classes showing it
                                  $(this).parent().removeClass('show');
                                  $(this).removeClass('show');
                              }
                          });
                          

                          CSS

                          @media(min-width:  768px) {
                            .dropdown-menu {
                              margin-top: 0; // fixes closing on slow mouse transition
                            }
                          }
                          

                          【讨论】:

                            【解决方案17】:

                            此解决方案打开和关闭

                            <script>
                            $(document).ready(function() {
                              // close all dropdowns that are open
                              $('body').click(function(e) {
                                  $('.nav-item.show').removeClass('show');
                                  //$('.nav-item.clicked').removeClass('clicked');
                                  $('.dropdown-menu.show').removeClass('show');
                              });
                            
                              $('.nav-item').click( function(e) {
                                $(this).addClass('clicked')
                              });
                            
                              // show dropdown for the link clicked
                              $('.nav-item').hover(function(e) {
                                  if ($('.nav-item.show').length < 1) {
                                    $('.nav-item.clicked').removeClass('clicked');
                                  }
                                  if ($('.nav-item.clicked').length < 1) {
                                      $('.nav-item.show').removeClass('show');
                                      $('.dropdown-menu.show').removeClass('show');
                                      $dd = $(this).find('.dropdown-menu');
                                      $dd.parent().addClass('show');
                                      $dd.addClass('show');
                                  }
                              });
                            });</script>
                            

                            要禁用 lg 大小的折叠菜单的悬停添加

                            if(( $(window).width() >= 992 )) {
                            

                            【讨论】:

                              【解决方案18】:

                              我认为这仅适用于 bootstrap 4,我内联添加,但您始终可以从脚本绑定事件。

                                <a 
                              onmouseover="$('#navbarDropdownMenuLink').dropdown('toggle')"
                              class="nav-link dropdown-toggle" 
                              href="http://example.com" 
                              id="navbarDropdownMenuLink" 
                              data-toggle="dropdown" 
                              aria-haspopup="true" 
                              aria-expanded="false">
                                    Dropdown link
                                  </a>
                              

                              【讨论】:

                              • 你打算将 jquery 脚本内嵌在一个普通的 javascript 事件处理程序中?
                              • 不要这样做。
                              【解决方案19】:

                              当我被要求将其更改为悬停交互时,我已经使用并设置了导航栏的样式,因此最终使用 jQuery 进行了修复。

                              function bootstrapHoverMenu (bp = 768) {
                              
                                // close all dropdowns that are open
                                  $('body').click( function (e) {
                                  $('.dropdown-menu.show').removeClass('show');
                                });
                              
                                // show dropdown for the link clicked
                                $('.nav-item').hover(function (e) {
                                  $('.dropdown-menu.show').removeClass('show');
                                  if(( $(window).width() >= bp )) {
                                    $dd = $(this).find('.dropdown-menu');
                                    $dd.addClass('show');
                                  }
                                });
                              
                                // get href for top level link if clicked and open
                                $('.dropdown').click(function (e) {
                                  if( $(window).width() < bp ) {
                                    $('.dropdown-menu').css({'display': 'none'});
                                  }
                                  $href = $(this).find('.nav-link').attr('href');
                                  window.open($href, '_self');
                                });
                              }
                              
                              $(document).ready( function() {
                                 // when page ready run the fix
                                 bootstrapHoverMenu();
                              });
                              

                              缺点是移动设备只有顶级链接。

                              【讨论】:

                              • 我认为 pureCSS 解决方案是最好的。
                              【解决方案20】:

                              自 v4 发布以来,Bootstrap 的功能似乎略有变化。除了 .dropdown 之外,.dropdown-menu 项目现在似乎还获得了 .show 类。我调整了 Andrei 的答案,以便在 .dropdown-menu 上切换课程。请注意,不再需要 CSS 并且 HTML 是相同的,只是我更新了当前版本的链接并且导航类更改为 navbar-expand-md

                              $('body').on('mouseenter mouseleave', '.dropdown', function (e) {
                                  var dropdown = $(e.target).closest('.dropdown');
                                  var menu = $('.dropdown-menu', dropdown);
                                  dropdown.addClass('show');
                                  menu.addClass('show');
                                  setTimeout(function () {
                                      dropdown[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
                                      menu[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
                                  }, 300);
                              });
                              <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
                              <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
                              <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
                              <nav class="navbar navbar-expand-md navbar-light bg-faded">
                                <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                                  <span class="navbar-toggler-icon"></span>
                                </button>
                                <a class="navbar-brand" href="#">Navbar</a>
                                <div class="collapse navbar-collapse" id="navbarNavDropdown">
                                  <ul class="navbar-nav">
                                    <li class="nav-item active">
                                      <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
                                    </li>
                                    <li class="nav-item">
                                      <a class="nav-link" href="#">Features</a>
                                    </li>
                                    <li class="nav-item">
                                      <a class="nav-link" href="#">Pricing</a>
                                    </li>
                                    <li class="nav-item dropdown">
                                      <a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                        Dropdown link
                                      </a>
                                      <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                                        <a class="dropdown-item" href="#">Action</a>
                                        <a class="dropdown-item" href="#">Another action</a>
                                        <a class="dropdown-item" href="#">Something else here</a>
                                      </div>
                                    </li>
                                  </ul>
                                </div>
                              </nav>

                              【讨论】:

                                【解决方案21】:

                                只需在样式表中添加这个简单的 css 代码,就可以开始了。

                                .dropdown:hover > .dropdown-menu {
                                    display: block;
                                }
                                .dropdown > .dropdown-toggle:active {
                                    /*Without this, clicking will make it sticky*/
                                    pointer-events: none;
                                }
                                

                                【讨论】:

                                • 这是最佳答案
                                • 不幸的是,这不是最好的答案;它错过了切换很多类和触发事件
                                • 加上折叠模式你不能再切换下拉菜单
                                • 对于 Bootstrap 4 它有效!仅当您不是在寻找事件触发事件时,才可以使用!
                                • 这是一个很好的解决方案,请务必在链接底部添加一些填充,以在将光标从链接移动到菜单时阻止下拉菜单关闭。
                                【解决方案22】:

                                &lt;div style="width: 100%; overflow: scroll;"&gt;&lt;table class="table table-striped table-bordered" style="font-size:12px"&gt;

                                【讨论】:

                                • 感谢您提供此代码 sn-p,它可能会提供一些即时帮助。正确解释would greatly improve 其教育价值,说明为什么这是一个很好的问题解决方案,并将使其对未来有类似但不相同问题的读者更有用。请编辑您的答案以添加解释,并说明适用的限制和假设。
                                • 这与问题无关。
                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2014-12-14
                                • 1970-01-01
                                • 2016-01-07
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多