简体   繁体   English

如何在 Bootstrap v4 中实现导航栏下拉悬停?

[英]How to implement a Navbar Dropdown Hover in Bootstrap v4?

I am a bit confused on the new bootstrap version since they changed dropdown menus to divs:我对新的引导程序版本有点困惑,因为他们将下拉菜单更改为 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>

Do you guys have any idea to get a hover dropdown in the Dropdown link in that snippet without adding additional script code (only css and script from bootstrap)?你们有没有想法在该片段的下拉链接中获得悬停下拉菜单而不添加额外的脚本代码(仅来自引导程序的 css 和脚本)? I already saw the bootstrap css classes and I can't relate with the ones in bootstrap V3 (I accomplish this without adding jquery in V3).我已经看到了 bootstrap css 类,我无法与 bootstrap V3 中的那些相关联(我没有在 V3 中添加 jquery 就完成了这个)。

Simple, CSS only solution:简单的、仅 CSS 的解决方案:

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

When clicked, it will still get the class show toggled to it (and will remain open when no longer hovered).单击时,它仍然会将类show切换到它(并且不再悬停时将保持打开状态)。


To get around this properly is to use events and properties reserved to pointer based devices: jQuery's mouseenter , mouseleave and :hover .正确解决此问题,请使用为基于指针的设备保留的事件和属性:jQuery 的mouseentermouseleave:hover Should work smoothly, intuitively, while not interfering at all with how the dropdown works on touch based devices.如果工作顺利,直观的,而不是在所有与下拉如何工作的在触摸设备的干扰。 Try it out, let me know if it works for you:试试看,让我知道它是否适合你:

Complete jQuery solution ( touch untouched):完整的jQuery 解决方案触摸未触及):

Pre v4.1.2 solution ( deprecated ): 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 shiplist introduced this change to how dropdowns work, making the solution above no longer work. v4.1.2 shiplist引入了对下拉列表工作方式的更改,使上述解决方案不再有效。
Here's the up to date solution for having the dropdown open on hover in v4.1.2 and above:这是在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>


Important note: If using the jQuery solution, it is important to remove the CSS one (or the dropdown won't close when .dropdown-toggle is clicked or when an menu option is clicked).重要提示:如果使用 jQuery 解决方案,删除 CSS 很重要(否则在单击.dropdown-toggle或单击菜单选项时下拉菜单不会关闭)。

Just Add this simple css code in your style-sheet and you are ready to go.只需在您的样式表中添加这个简单的css代码,您就可以开始使用了。

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

Bootstrap 4 CSS-only Bootstrap 4 仅 CSS

None of the CSS only answers work entirely.没有一个 CSS 只有答案完全有效。 Either the dropdown menu stays open after click, or there is a gap that makes the dropdown menu hide before you can reach the menu links to click.单击后下拉菜单保持打开状态,或者在您可以到达要单击的菜单链接之前,有一个间隙使下拉菜单隐藏。

Here's the simple CSS only solution:这是仅使用 CSS 的简单解决方案:

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

Remove data-toggle=dropdown from the HTML markup to prevent the dropdown staying open in click.从 HTML 标记中删除data-toggle=dropdown以防止下拉列表在单击时保持打开状态。 Use mt-0 (margin-top:0) to eliminate the gap above the menu, and make it possible to hover the menu items.使用mt-0 (margin-top:0) 消除菜单上方的间隙,并使悬停菜单项成为可能。

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


Complete Code:完整代码:

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

Andrei's "complete" jQuery+CSS solution has the right intent, but it's verbose and still incomplete. Andrei 的“完整” jQuery+CSS 解决方案具有正确的意图,但它冗长而且仍然不完整。 Incomplete because while it probably covers all the necessary DOM changes, it's missing the firing of custom events .不完整,因为虽然它可能涵盖了所有必要的 DOM 更改,但它缺少 自定义事件的触发。 Verbose because it's wheel-reinventing when Bootstrap already provides thedropdown() method , which does everything.冗长,因为当 Bootstrap 已经提供dropdown() 方法时它是轮子重新发明,它可以完成所有事情。

So the correct, DRY solution, which does not rely on the CSS hack often repeated among other answers, is just jQuery :因此,不依赖于其他答案中经常重复的 CSS hack 的正确的 DRY 解决方案就是 jQuery

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

Bootstrap's functionality appears to have changed slightly since v4 has been released.自 v4 发布以来,Bootstrap 的功能似乎略有变化。 The .dropdown-menu item appears to also now get the .show class in addition to the .dropdown ..dropdown-menu项出现到现在也得到了.show类除了.dropdown I adapted Andrei's answer to also toggle the class on the .dropdown-menu .我改编了安德烈的回答,也可以在.dropdown-menu上切换课程。 Note that the CSS is no longer necessary and the HTML is the same except I updated the links to the current versions and the nav class changed to navbar-expand-md .请注意,不再需要 CSS 并且 HTML 是相同的,除了我更新了当前版本的链接并且 nav 类更改为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>

I had already used and styled a navbar when I was requested to change it to a hover interaction instead, so ended up with this as a fix using jQuery.当我被要求将其更改为悬停交互时,我已经使用并设置了导航栏的样式,因此最终将其作为使用 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();
});

Downside is mobile only has top level links.缺点是移动设备只有顶级链接。

Bootstrap v4 Solution - jQuery based, but better than a pure css solution Bootstrap v4 解决方案 - 基于 jQuery,但比纯 css 解决方案更好

This ensures that you can still follow top level link clicks and is compatible with mobile.这可确保您仍然可以关注顶级链接点击次数并与移动设备兼容。

This was built with desktop and mobile in mind.这是在考虑桌面和移动设备的情况下构建的。 Fell free to wrap the jQuery with a conditional that checks if the window width is greater than 768px.随意用一个检查窗口宽度是否大于 768px 的条件来包装 jQuery。

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 CSS

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

Hoverable dropdown without losing functionality of popper.js for bootstrap 4 only可悬停下拉菜单,而不会丢失 popper.js 的功能,仅适用于 bootstrap 4

Javascript Javascript

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

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

This solution switches on and off此解决方案打开和关闭

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

To disable the hover for lg sized collapse menus add要禁用 lg 大小的折叠菜单的悬停添加

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

CSS solutions not working properly on touch device CSS 解决方案在触摸设备上无法正常工作

I found that any CSS solutions made the menu stay open on touch devices, they didn't collapse anymore.我发现任何 CSS 解决方案都使菜单在触摸设备上保持打开状态,它们不再折叠。

So I read the article: https://www.brianshim.com/webtricks/drop-down-menus-on-ios-and-android/ (by Brian Shim)所以我读了这篇文章: https : //www.brianshim.com/webtricks/drop-down-menus-on-ios-and-android/ (作者:Brian Shim)
Very useful!很有用! It states that a touch device always first checks the existence of a hover class on an element.它指出触摸设备总是首先检查元素上是否存在悬停类。

But: by using jQuery .show() you introduce a style attribute (display:block;) that makes the menu open up on first touch.但是:通过使用 jQuery .show() 您引入了一个样式属性 (display:block;),它使菜单在第一次触摸时打开。 Now the menu has opened without the bootstrap 'show' class.现在菜单已经打开,没有引导程序“显示”类。 If a user chooses a link from the dropdown menu it works perfectly.如果用户从下拉菜单中选择一个链接,它就可以完美运行。 But if a user decides to close the menu without using it he has to tap twice to close the menu: At the first tap the original bootstrap 'show' class gets attached so the menu opens up again, at the second tap the menu closes due to normal bootstrap behaviour (removal of 'show' class).但是如果用户决定不使用它就关闭菜单,他必须点击两次才能关闭菜单:在第一次点击时,原始引导程序“show”类被附加,因此菜单再次打开,在第二次点击时菜单关闭到正常的引导行为(删除“显示”类)。

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

He has some very handy ways of detecting touch or hover devices.他有一些非常方便的方法来检测触摸或悬停设备。

So, combined the two authors with a bit jQuery of my own:因此,将两位作者与我自己的一些 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);
               });
             });
          });
      };

}); }); Check once if a device allows a hover event.检查一次设备是否允许悬停事件。 If it does, introduce the possibility to hover using .show().如果是,请引入使用 .show() 悬停的可能性。 If the device doesn't allow a hover event, the .show() never gets introduced so you get natural bootstrap behaviour on touch device.如果设备不允许悬停事件,则 .show() 永远不会被引入,因此您可以在触摸设备上获得自然的引导行为。

Be sure to remove any CSS regarding menu hover classes.请务必删除有关菜单悬停类的任何 CSS。

Took me three days :) so I hope it helps some of you.我花了三天 :) 所以我希望它可以帮助你们中的一些人。

1. Remove data-toggle="dropdown" attribute (so click will not open dropdown menu) 1. 移除 data-toggle="dropdown" 属性(所以点击不会打开下拉菜单)

2. Add :hover pseudo-class to show dropdown-menu 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>

I think this simply just work with bootstrap 4, i adding in inline but you always can bind event from script.我认为这仅适用于 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>

I use bootstrap 4.0.0 since we want to simulate .show to hover event, it simply easy.我使用 bootstrap 4.0.0,因为我们想模拟.show来悬停事件,这很简单。 just add all styles in .dropdown.show .dropdown-menu to the :hover .只需将.dropdown.show .dropdown-menu中的所有样式添加到:hover like this:像这样:

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

 $('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>

CSS and Desktop only solution仅 CSS 和桌面解决方案

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

Neither of the top solutions worked for me.两种顶级解决方案都不适合我。

This works perfectly, keeps submenus open while browsing, add uses the native Bootstrap javascript.这完美地工作,在浏览时保持子菜单打开,添加使用本机 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');
});

Google brought me here but... The examples provided work if the dropdown menu is overlaping (at least by 1px) with its parent when show.谷歌把我带到这里但是......如果下拉菜单在显示时与其父级重叠(至少 1px),则示例提供了工作。 If not, it loses focus and nothing works as intended.如果没有,它会失去焦点并且没有任何效果。

Here is a working solution with jQuery and Bootstrap 4.5.2 :这是一个使用 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');
        }
    });

I couldn't find here the full solution.我在这里找不到完整的解决方案。 So, it's my one which works with Bootstrap v4.4.1 and has the next benefits :所以,这是我的一个与 Bootstrap v4.4.1 一起使用并具有以下好处

  • A click on the dropdown-toggle works as a normal nav link.单击dropdown-toggle可用作普通导航链接。

  • Supports any nesting level of dropdown menus.支持任何嵌套级别的下拉菜单。

  • Bootstrap 4 {show/shown/hide/hidden}.bs.dropdown events work well. 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. }

If you don't use ES6 just change arrow functions to the old function style.如果您不使用 ES6,只需将箭头函数更改为旧函数样式。

Thanks, @tao for your example, it was helpful for me.谢谢,@tao 举个例子,这对我很有帮助。

Code related links: B4 Dropdown Events , viewport (Responsive Bootstrap Toolkit) , WP Bootstrap Navwalker .代码相关链接: B4 下拉事件视口(响应式引导工具包)WP Bootstrap Navwalker

just use Tao's CSS code:只需使用 Tao 的 CSS 代码:

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

and remove the 2px-gap between the .dropdown-toggle and the .dropdown-menu by setting its top-margin to zero:并通过将其 top-margin 设置为零来删除 .dropdown-toggle 和 .dropdown-menu 之间的 2px-gap:

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

all I am working with bootstrap 5, above solutions were looking big I just removed data-bs-toggle='dropdown' because it was blocking the parent link to navigate and toggling script to open the dropdown on click.我正在使用 bootstrap 5,上面的解决方案看起来很大我刚刚删除了data-bs-toggle='dropdown'因为它阻止了父链接导航并切换脚本以在单击时打开下拉列表。

And added CSS并添加了 CSS

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

Works fine for me对我来说很好用

(June 2020) I found this solution and I thought I should post it here: (2020 年 6 月)我找到了这个解决方案,我想我应该把它贴在这里:

Bootstrap version: 4.3.1引导程序版本: 4.3.1

The CSS part: 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;
}

The jQuery part: 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");
  }
});

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM