如何使Twitter Bootstrap菜单下拉悬停而不是点击

我想让我的引导菜单在悬停时自动下拉,而不必单击菜单标题。我还想去掉菜单标题旁边的小箭头。

847231 次浏览

要让菜单自动放置在悬停上,这可以使用基本的CSS来实现。您需要将选择器设置为隐藏菜单选项,然后将其设置为在适当的li标记悬停时显示为块。以twitter bootstrap页面为例,选择器如下:

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

但是,如果您使用Bootstrap的响应式功能,您不希望在折叠的导航栏(在较小的屏幕上)上使用此功能。为了避免这种情况,请将上面的代码包装在媒体查询中:

@media (min-width: 979px) {ul.nav li.dropdown:hover > ul.dropdown-menu {display: block;}}

要隐藏箭头(插入符号),可以通过不同的方式完成,具体取决于您使用的是Twitter Bootstrap版本2及更低版本还是版本3:

bootstrap3

要在版本3中删除插入符号,您只需要从.dropdown-toggle锚元素中删除超文本标记语言<b class="caret"></b>

<a class="dropdown-toggle" data-toggle="dropdown" href="#">Dropdown<b class="caret"></b>    <-- remove this line</a>

Bootstrap 2及更低

要删除版本2中的插入符号,您需要对CSS有更多的了解,我建议更详细地查看:after伪元素的工作原理。为了让您开始理解、定位和删除twitter bootstrap示例中的箭头,您将使用以下CSS选择器和代码:

a.menu:after, .dropdown-toggle:after {content: none;}

如果你进一步研究这些方法是如何工作的,而不仅仅是使用我给你的答案,这将对你有利。

感谢@CocaAkat指出我们缺少“>”子组合器以防止子菜单显示在父悬停上

除了“我的头很痛”(这是伟大的)的答案:

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

有两个挥之不去的问题:

  1. 单击下拉链接将打开下拉菜单。它将保持打开状态,除非用户单击其他位置,或者将鼠标悬停在它上面,从而创建一个尴尬的UI。
  2. 下拉链接和下拉菜单之间有1像素的边距。如果您在下拉菜单和下拉菜单之间缓慢移动,这会导致下拉菜单隐藏。

(1)的解决方案是从导航链接中删除“class”和“data-toggle”元素

<a href="#">Dropdown<b class="caret"></b></a>

这也使您能够创建指向父页面的链接——这在默认实现中是不可能的。您只需将“#”替换为您要发送给用户的任何页面。

(2)的解决方案是删除. dropdown菜单选择器上的边缘顶部

.navbar .dropdown-menu {margin-top: 0px;}

这可能是一个愚蠢的想法,但要删除指向下方的箭头,您可以删除

<b class="caret"></b>

不过,这对向上指向的人没有任何帮助…

如果它们比平板电脑小,这应该会隐藏下拉列表和它们的插入符号。

@media (max-width: 768px) {.navbar ul.dropdown-menu, .navbar li.dropdown b.caret {display: none;}}

这会把上面的藏起来

.navbar .dropdown-menu:before {display:none;}.navbar .dropdown-menu:after {display:none;}

我创建了一个基于最新(v2.0.2)Bootstrap框架的纯悬停下拉框,该框架支持多个子菜单,并认为我将其发布给未来的用户:

body {padding-top: 60px;padding-bottom: 40px;}
.sidebar-nav {padding: 9px 0;}
.dropdown-menu .sub-menu {left: 100%;position: absolute;top: 0;visibility: hidden;margin-top: -1px;}
.dropdown-menu li:hover .sub-menu {visibility: visible;}
.dropdown:hover .dropdown-menu {display: block;}
.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu,.navbar .dropdown-menu {margin-top: 0;}
.navbar .sub-menu:before {border-bottom: 7px solid transparent;border-left: none;border-right: 7px solid rgba(0, 0, 0, 0.2);border-top: 7px solid transparent;left: -7px;top: 10px;}
.navbar .sub-menu:after {border-top: 6px solid transparent;border-left: none;border-right: 6px solid #fff;border-bottom: 6px solid transparent;left: 10px;top: 11px;left: -6px;}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet" />
<div class="navbar navbar-fixed-top"><div class="navbar-inner"><div class="container-fluid"><a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></a><a href="#" class="brand">Project name</a><div class="nav-collapse"><ul class="nav"><li class="active"><a href="#">Home</a></li><li><a href="#">Link</a></li><li><a href="#">Link</a></li><li><a href="#">Link</a></li><li class="dropdown"><a data-toggle="dropdown" class="dropdown-toggle" href="#">Dropdown <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="#">2-level Dropdown <i class="icon-arrow-right"></i></a><ul class="dropdown-menu sub-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li class="nav-header">Nav header</li><li><a href="#">Separated link</a></li><li><a href="#">One more separated link</a></li></ul></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li class="nav-header">Nav header</li><li><a href="#">Separated link</a></li><li><a href="#">One more separated link</a></li></ul></li></ul><form action="" class="navbar-search pull-left"><input type="text" placeholder="Search" class="search-query span2"></form><ul class="nav pull-right"><li><a href="#">Link</a></li><li class="divider-vertical"></li><li class="dropdown"><a class="#" href="#">Menu</a></li></ul></div><!-- /.nav-collapse --></div></div></div>
<hr>
<ul class="nav nav-pills"><li class="active"><a href="#">Regular link</a></li><li class="dropdown"><a href="#" data-toggle="dropdown" class="dropdown-toggle">Dropdown <b class="caret"></b></a><ul class="dropdown-menu" id="menu1"><li><a href="#">2-level Menu <i class="icon-arrow-right"></i></a><ul class="dropdown-menu sub-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li class="nav-header">Nav header</li><li><a href="#">Separated link</a></li><li><a href="#">One more separated link</a></li></ul></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li><a href="#">Separated link</a></li></ul></li><li class="dropdown"><a href="#">Menu</a></li><li class="dropdown"><a href="#">Menu</a></li></ul>

演示

我使用了一些jQuery:

// Add hover effect to menusjQuery('ul.nav li.dropdown').hover(function() {jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();}, function() {jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();});

使用jQuery更好:

jQuery('ul.nav li.dropdown').hover(function() {jQuery(this).find('.dropdown-menu').stop(true, true).show();jQuery(this).addClass('open');}, function() {jQuery(this).find('.dropdown-menu').stop(true, true).hide();jQuery(this).removeClass('open');});

[更新]该插件位于github上,我正在进行一些改进(例如仅使用数据属性(不需要JS)。我将代码留在下面,但它与GitHub上的不同。

我喜欢纯CSS版本,但是在它关闭之前有一个延迟是很好的,因为它通常是一个更好的用户体验(即不会因为鼠标滑出下拉列表之外的1 px而受到惩罚,等等),正如评论中提到的,你必须处理1px的保证金,或者有时当你从原始按钮移动到下拉列表时,导航意外关闭,等等。

我创建了一个快速的小插件,我在几个网站上使用过,它工作得很好。每个导航项都是独立处理的,所以它们有自己的延迟计时器等。

JS

// outside the scope of the jQuery plugin to// keep track of all dropdownsvar $allDropdowns = $();
// if instantlyCloseOthers is true, then it will instantly// shut other nav items when a new one is hovered over$.fn.dropdownHover = function(options) {
// the element we really care about// is the dropdown-toggle's parent$allDropdowns = $allDropdowns.add(this.parent());
return this.each(function() {var $this = $(this).parent(),defaults = {delay: 500,instantlyCloseOthers: true},data = {delay: $(this).data('delay'),instantlyCloseOthers: $(this).data('close-others')},options = $.extend(true, {}, defaults, options, data),timeout;
$this.hover(function() {if(options.instantlyCloseOthers === true)$allDropdowns.removeClass('open');
window.clearTimeout(timeout);$(this).addClass('open');}, function() {timeout = window.setTimeout(function() {$this.removeClass('open');}, options.delay);});});};

delay参数非常不言自明,当您将鼠标悬停在一个新下拉列表上时,instantlyCloseOthers将立即关闭所有其他打开的下拉列表。

不是纯CSS,但希望能在这么晚的时候帮助其他人(即这是一个旧线程)。

如果你愿意,你可以看到我经历的不同过程(在#concrete5 IRC的讨论中),通过这个要点中的不同步骤让它工作:https://gist.github.com/3876924

插件模式方法更清晰地支持单个计时器等。

查看博客文章了解更多。

只是想补充一下,如果你有多个下拉列表(就像我一样),你应该写:

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

它会正常工作。

jQuery解决方案很好,但它需要处理点击事件(对于手机或平板电脑),因为悬停无法正常工作……也许可以做一些窗口重新大小检测?

安德烈斯·伊里奇的回答似乎很有效,但应该用媒体查询来包装:

@media (min-width: 980px) {
.dropdown-menu .sub-menu {left: 100%;position: absolute;top: 0;visibility: hidden;margin-top: -1px;}
.dropdown-menu li:hover .sub-menu {visibility: visible;}
.dropdown:hover .dropdown-menu {display: block;}
.nav-tabs .dropdown-menu, .nav-pills .dropdown-menu, .navbar .dropdown-menu {margin-top: 0;}
.navbar .sub-menu:before {border-bottom: 7px solid transparent;border-left: none;border-right: 7px solid rgba(0, 0, 0, 0.2);border-top: 7px solid transparent;left: -7px;top: 10px;}.navbar .sub-menu:after {border-top: 6px solid transparent;border-left: none;border-right: 6px solid #fff;border-bottom: 6px solid transparent;left: 10px;top: 11px;left: -6px;}}

这适用于WordPress Bootstrap:

.navbar .nav > li > .dropdown-menu:after,.navbar .nav > li > .dropdown-menu:before {content: none;}

在我看来,最好的方法是这样的:

;(function($, window, undefined) {// Outside the scope of the jQuery plugin to// keep track of all dropdownsvar $allDropdowns = $();
// If instantlyCloseOthers is true, then it will instantly// shut other nav items when a new one is hovered over$.fn.dropdownHover = function(options) {
// The element we really care about// is the dropdown-toggle's parent$allDropdowns = $allDropdowns.add(this.parent());
return this.each(function() {var $this = $(this),$parent = $this.parent(),defaults = {delay: 500,instantlyCloseOthers: true},data = {delay: $(this).data('delay'),instantlyCloseOthers: $(this).data('close-others')},settings = $.extend(true, {}, defaults, options, data),timeout;
$parent.hover(function(event) {
// So a neighbor can't open the dropdownif(!$parent.hasClass('open') && !$this.is(event.target)) {return true;}
if(settings.instantlyCloseOthers === true)$allDropdowns.removeClass('open');
window.clearTimeout(timeout);$parent.addClass('open');}, function() {timeout = window.setTimeout(function() {$parent.removeClass('open');}, settings.delay);});
// This helps with button groups!$this.hover(function() {if(settings.instantlyCloseOthers === true)$allDropdowns.removeClass('open');
window.clearTimeout(timeout);$parent.addClass('open');});
// Handle submenus$parent.find('.dropdown-submenu').each(function(){var $this = $(this);var subTimeout;$this.hover(function() {window.clearTimeout(subTimeout);$this.children('.dropdown-menu').show();
// Always close submenu siblings instantly$this.siblings().children('.dropdown-menu').hide();}, function() {var $submenu = $this.children('.dropdown-menu');subTimeout = window.setTimeout(function() {$submenu.hide();}, settings.delay);});});});};
$(document).ready(function() {// apply dropdownHover to all elements with the data-hover="dropdown" attribute$('[data-hover="dropdown"]').dropdownHover();});})(jQuery, this);

示例标记:

<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-delay="1000" data-close-others="false">Account <b class="caret"></b></a><ul class="dropdown-menu"><li><a tabindex="-1" href="#">My Account</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Change Email</a></li><li><a tabindex="-1" href="#">Change Password</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Logout</a></li></ul></li>

我的操作如下:

$('ul.nav li.dropdown').hover(function(){$(this).children('ul.dropdown-menu').slideDown();}, function(){$(this).children('ul.dropdown-menu').slideUp();});

我希望这能帮助一些人……

用这个脚本覆盖bootstrap.js。

jQuery(document).ready(function ($) {$('.navbar .dropdown').hover(function() {$(this).addClass('extra-nav-class').find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();}, function() {var na = $(this)na.find('.dropdown-menu').first().stop(true, true).delay(100).slideUp('fast', function(){ na.removeClass('extra-nav-class') })});
$('.dropdown-submenu').hover(function() {$(this).addClass('extra-nav-class').find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();}, function() {var na = $(this)na.find('.dropdown-menu').first().stop(true, true).delay(100).slideUp('fast', function(){ na.removeClass('extra-nav-class') })});
});

这里有很多非常好的解决方案。但我想我会继续把我的放在这里作为另一个选择。这只是一个简单的jQuery片段,它的方式就像引导程序一样,如果它支持悬停下拉而不是单击。我只在版本3上测试过这个,所以我不知道它是否适用于版本2。在你的编辑器中将其保存为一个片段,只需按一下键就可以了。

<script>$(function() {$(".dropdown").hover(function(){ $(this).addClass('open') },function(){ $(this).removeClass('open') });});</script>

基本上,它只是说当你将鼠标悬停在下拉类上时,它会将开放类添加到其中。然后它就可以正常工作了。当你停止将鼠标悬停在带有下拉类的父li或子ul/li的时,它会删除开放类。显然,这只是众多解决方案中的一种,你可以添加到它以使其仅适用于. dropdown的特定实例。或者添加到父级或子级的转换。

这是我的技巧,在您停止将鼠标悬停在菜单或切换按钮上后,在菜单关闭之前添加一个轻微的延迟。您通常单击以显示导航菜单的<button>#nav_dropdown

$(function() {var delay_close_it, nav_menu_timeout, open_it;nav_menu_timeout = void 0;open_it = function() {if (nav_menu_timeout) {clearTimeout(nav_menu_timeout);nav_menu_timeout = null;}return $('.navbar .dropdown').addClass('open');};delay_close_it = function() {var close_it;close_it = function() {return $('.navbar .dropdown').removeClass('open');};return nav_menu_timeout = setTimeout(close_it, 500);};$('body').on('mouseover', '#nav_dropdown, #nav_dropdown *', open_it).on('mouseout', '#nav_dropdown', delay_close_it);return $('body').on('mouseover', '.navbar .dropdown .dropdown-menu', open_it).on('mouseout', '.navbar .dropdown .dropdown-menu', delay_close_it);});

最好的方法是通过悬停触发Bootstrap的单击事件。这样,它仍然应该保持触摸设备友好。

$('.dropdown').hover(function(){$('.dropdown-toggle', this).trigger('click');});

所以你有这个代码:

<a class="dropdown-toggle" data-toggle="dropdown">Show menu</a>
<ul class="dropdown-menu" role="menu"><li>Link 1</li><li>Link 2</li><li>Link 3</li></ul>

通常它适用于单击事件,而你希望它适用于悬停事件。这很简单,只需使用以下JavaScript/jQuery代码:

$(document).ready(function () {$('.dropdown-toggle').mouseover(function() {$('.dropdown-menu').show();})
$('.dropdown-toggle').mouseout(function() {t = setTimeout(function() {$('.dropdown-menu').hide();}, 100);
$('.dropdown-menu').on('mouseenter', function() {$('.dropdown-menu').show();clearTimeout(t);}).on('mouseleave', function() {$('.dropdown-menu').hide();})})})

这非常有效,解释如下:我们有一个按钮和一个菜单。当我们悬停在按钮上时,我们会显示菜单,当我们鼠标退出按钮时,我们会在100毫秒后隐藏菜单。如果你想知道我为什么使用它,是因为你需要时间将光标从按钮拖到菜单上。当你在菜单上时,时间被重置,你可以在那里停留任意时间。当你退出菜单时,我们会立即隐藏菜单,没有任何超时。

我在许多项目中使用过这段代码,如果您在使用它时遇到任何问题,请随时问我问题。

只需用三行代码自定义您的CSS样式

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

还添加了利润率-top: 0来重置. dropdown菜单的引导css边距,以便当用户从下拉菜单缓慢悬停到菜单列表时,菜单列表不会消失。

ul.nav li.dropdown:hover > ul.dropdown-menu {display: block;}
.nav .dropdown-menu {margin-top: 0;}

我们看到,除了答案从我的头好痛”,“科里·普莱斯”发现了两个问题:

问题1:单击下拉链接将打开下拉菜单。除非用户单击某处,否则它将保持打开状态否则,或者悬停在它上面,创建一个尴尬的UI。

解决方案:从导航链接中删除“class”和“data-toggle”元素

解决方案几乎是完美的,但这里的问题是,当涉及到移动设备和平板电脑,它不会工作!

我正在使用一些jQuery代码来解决这个问题。

if ($(window).width() > 769) {$('.dropdown-toggle').removeAttr('data-toggle');$('.dropdown-menu').removeAttr('style');$('.dropdown').removeClass('open');}$(window).resize(function () {if ($(window).width() > 769) {$('.dropdown-toggle').removeAttr('data-toggle');$('.dropdown-menu').removeAttr('style');$('.dropdown').removeClass('open');}else {$('.dropdown-toggle').attr("data-toggle", "dropdown");}});

说明:这里我们假设移动设备和平板电脑的崩溃是从768px开始的。

如果你有一个像这样的dropdown类的元素(例如):

<ul class="list-unstyled list-inline"><li class="dropdown"><a data-toggle="dropdown" href="#"><i class="fa fa-bars"></i> Dropdown 1</a><ul class="dropdown-menu"><li><a href="">Item 1</a></li><li><a href="">Item 2</a></li><li><a href="">Item 3</a></li><li><a href="">Item 4</a></li><li><a href="">Item 5</a></li></ul></li><li class="dropdown"><a data-toggle="dropdown" href="#"><i class="fa fa-user"></i> Dropdown 2</a><ul class="dropdown-menu"><li><a href="">Item A</a></li><li><a href="">Item B</a></li><li><a href="">Item C</a></li><li><a href="">Item D</a></li><li><a href="">Item E</a></li></ul></li></ul>

然后,您可以使用这段jQuery代码片段在悬停时自动下拉框,而不必单击其标题:

<script>$('.dropdown').hover(function() {$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();},function() {$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();});
$('.dropdown-menu').hover(function() {$(this).stop(true, true);},function() {$(this).stop(true, true).delay(200).fadeOut();});</script>

这是一个演示

这个答案依赖于@Michael回答,我做了一些修改并添加了一些补充以使下拉框正常工作

对于插入符号……我还没有看到任何一个指定简单的CSS完全阻止插入符号。

在这里你去:

.caret {display: none !important;}

使用两个内联链接。使用下拉切换隐藏链接,并在可见链接上添加onmouseover事件以单击下拉框。

<a class="pretty-button"href="#" alt="Notifications"onmouseover="$('#notifications-dropdown').click()"></a>
<a style="display:none"id="notifications-dropdown"class="js-nav js-tooltip js-dynamic-tooltip"href="#"alt="Notifications"data-toggle="dropdown"><span class="fa fa-flag fa-2x"></span></a>

为了增强苏达山的回答,我将其包装在媒体查询中,以防止在XS显示宽度上悬停…

@media (min-width:768px){ul.nav li.dropdown:hover > ul.dropdown-menu {display: block;}
.nav .dropdown-menu {margin-top: 0;}}

标记中的插入符号也不是必需的,只是li下拉框类。

我已经发布了Bootstrap 3下拉悬停功能的适当的插件,您甚至可以在其中定义单击dropdown-toggle元素时会发生什么(可以禁用单击):

https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover


为什么我已经有很多解决方案了?

我对所有以前存在的解决方案都有问题。简单的CSS没有在.dropdown上使用.open类,所以当下拉可见时,下拉切换元素不会有反馈。

js的会干扰点击.dropdown-toggle,所以下拉框会在悬停时显示,然后在点击打开的下拉框时隐藏它,鼠标移出会触发下拉框再次显示。一些js解决方案正在破坏iOS兼容性,一些插件无法在支持触摸事件的现代桌面浏览器上运行。

这就是为什么我做了引导下拉悬停插件,它可以防止仅使用标准的Bootstrap javascript API,没有任何黑客攻击出现所有这些问题。即使是Aria属性也可以很好地使用这个插件。

您可以使用默认的$().dropdown('toggle')方法在悬停时切换下拉框:

$(".nav .dropdown").hover(function() {$(this).find(".dropdown-toggle").dropdown("toggle");});

这对我有效:

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

这是JSFiddle->https://jsfiddle.net/PRkonsult/mn31qf0p/1/

底部的JavaScript位是真正的魔法。

超文本标记语言

<!--http://getbootstrap.com/components/#navbar--><div class="body-wrap"><div class="container"><nav class="navbar navbar-inverse" role="navigation"><div class="container-fluid"><!-- Brand and toggle get grouped for better mobile display --><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="#">Brand</a></div>
<!-- Collect the nav links, forms, and other content for toggling --><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li class="active"><a href="#">Link</a></li><li><a href="#">Link</a></li><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li><a href="#">Separated link</a></li><li class="divider"></li><li><a href="#">One more separated link</a></li></ul></li></ul>
<ul class="nav navbar-nav navbar-right"><li><a href="#">Link</a></li><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li><a href="#">Separated link</a></li></ul></li></ul></div><!-- /.navbar-collapse --></div><!-- /.container-fluid --></nav></div></div>

css

/* Bootstrap dropdown hover menu */
body {font-family: 'PT Sans', sans-serif;font-size: 13px;font-weight: 400;color: #4f5d6e;position: relative;background: rgb(26, 49, 95);background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(26, 49, 95, 1)), color-stop(10%, rgba(26, 49, 95, 1)), color-stop(24%, rgba(29, 108, 141, 1)), color-stop(37%, rgba(41, 136, 151, 1)), color-stop(77%, rgba(39, 45, 100, 1)), color-stop(90%, rgba(26, 49, 95, 1)), color-stop(100%, rgba(26, 49, 95, 1)));filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#1a315f', endColorstr='#1a315f', GradientType=0);}
.body-wrap {min-height: 700px;}
.body-wrap {position: relative;z-index: 0;}
.body-wrap: before,.body-wrap: after {content: '';position: absolute;top: 0;left: 0;right: 0;z-index: -1;height: 260px;background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(26, 49, 95, 1)), color-stop(100%, rgba(26, 49, 95, 0)));background: linear-gradient(to bottom, rgba(26, 49, 95, 1) 0%, rgba(26, 49, 95, 0) 100%);filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#1a315f', endColorstr='#001a315f', GradientType=0);}
.body-wrap:after {top: auto;bottom: 0;background: linear-gradient(to bottom, rgba(26, 49, 95, 0) 0%, rgba(26, 49, 95, 1) 100%);filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#001a315f', endColorstr='#1a315f', GradientType=0);}
nav {margin-top: 60px;box-shadow: 5px 4px 5px #000;}

然后是JavaScript代码的重要部分:

$('ul.nav li.dropdown').hover(function() {$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);}, function() {$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);});

使用此代码打开mousehover上的子菜单(仅限桌面):

$('ul.nav li.dropdown').hover(function () {if ($(window).width() > 767) {$(this).find('.dropdown-menu').show();}}, function () {if ($(window).width() > 767) {$(this).find('.dropdown-menu').hide().css('display','');}});

如果您希望第一级菜单可点击,即使在移动设备上也可以添加:

    $('.dropdown-toggle').click(function() {if ($(this).next('.dropdown-menu').is(':visible')) {window.location = $(this).attr('href');}});

子菜单(下拉菜单)将在桌面上使用鼠标悬停打开,在手机和平板电脑上使用单击/触摸打开。打开子菜单后,第二次单击将允许您打开链接。由于if ($(window).width() > 767),子菜单将在移动设备上采用全屏宽度。

$('.dropdown').hover(function(e){$(this).addClass('open')})

我希望这有帮助。检查链接https://jsfiddle.net/awb7gfb1/

<nav><div id="menubar" class=" collapse navbar-collapse row"><ul id="dropdownNavbar" class="nav navbar-nav"><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-time"></span>Time Card<span class="caret"></span></button><div class="dropdown-content"><a id="showTimeCard" href="#">My Time Card</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a><a href="#">Sub Menu 4</a><a href="#">Sub Menu 5</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-stats"></span>Project<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-user"></span>HR Links<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-screenshot"></span>Leave Tracker<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a><a href="#">Sub Menu 4</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-briefcase"></span>Accounts<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a><a href="#">Sub Menu 4</a><a href="#">Sub Menu 5</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-headphones"></span>Service Desk<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a><a href="#">Sub Menu 4</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-file"></span>Reports<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a><a href="#">Sub Menu 4</a><a href="#">Sub Menu 5</a></div></li><li class="dropdown"><button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-cog"></span>Settings<span class="caret"></span></button><div class="dropdown-content"><a href="#">Sub Menu 1</a><a href="#">Sub Menu 2</a><a href="#">Sub Menu 3</a></div></li></ul></div></nav>

和CSS

.dropdown {float: left;padding-right: 1px;}
.dropbtn{border: 0px;height: 30px;border-radius: 0px 10px;}li button, .dropbtn {display: inline-block;color: white;text-align: center;}
li button:hover, .dropdown:hover .dropbtn {background-color: #12A5F4;}
.dropbtn.active {background: #12A5F4;}
.dropdown-content {display: none;position: absolute;background-color: #e8f3f4;min-width: 100%;box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);z-index: 10;}
.navbar-header{overflow: visible;z-index: 1;}
.dropdown-content a {color: black;padding: 5px 10px;display: block;text-align: left;}
.dropdown-content a:hover {background-color: #d8dee2}
.dropdown:hover .dropdown-content {display: block;}
#menubar{padding-top: 5px;overflow: visible;z-index: 10;padding-left: 0px;padding-right: 0px;margin: 0px;}
#dropdownNavbar{margin: 0px;}
.navbar-toggle{background-color: #3382d5;}.navbar-toggle span{background-color: white;}
 <ul class="nav navbar-nav"><li class="active"><a href="#">Link</a></li><li><a href="#">Link</a></li><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a><ul class="dropdown-menu"><li><a href="#">Action</a></li><li><a href="#">Another action</a></li><li><a href="#">Something else here</a></li><li class="divider"></li><li><a href="#">Separated link</a></li><li class="divider"></li><li><a href="#">One more separated link</a></li></ul></li></ul><script>$('ul.nav li.dropdown').hover(function() {$(this).find('.dropdown-menu').stop(true,true).delay(200).fadeIn(500);}, function() {$(this).find('.dropdown-menu').stop(true,true).delay(200).fadeOut(500);});</script>

<!DOCTYPE html><html><head><style>.dropbtn {background-color: #4CAF50;color: white;padding: 16px;font-size: 16px;border: none;cursor: pointer;}
.dropdown {position: relative;display: inline-block;}
.dropdown-content {display: none;position: absolute;background-color: #f9f9f9;min-width: 160px;box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);z-index: 1;}
.dropdown-content a {color: black;padding: 12px 16px;text-decoration: none;display: block;}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {display: block;}
.dropdown:hover .dropbtn {background-color: #3e8e41;}</style></head><body>
<h2>Hoverable Dropdown</h2><p>Move the mouse over the button to open the dropdown menu.</p>
<div class="dropdown"><button class="dropbtn">Dropdown</button><div class="dropdown-content"><a href="#">Link 1</a><a href="#">Link 2</a><a href="#">Link 3</a></div></div>
</body></html>

最标准的答案:

  • 支持aria-扩展属性
  • 支持非触摸设备
  • 支持触摸设备
  • 支持所有下拉列表
var isTouchDevice = (('ontouchstart' in window) ||(navigator.MaxTouchPoints > 0) ||(navigator.msMaxTouchPoints > 0));if(!isTouchDevice){// open dropdowns on hover on non mobile devices$(".dropdown").hover(function(e) {$('.dropdown-toggle', this).dropdown("toggle");e.stopPropagation();});// prevent blinkling$(".submenu-link").click(function(e) {e.stopPropagation();});}

如果需要,您可以将$(".dropdown")更改为特定区域:

$("#top-menu .dropdown")

这是Bootstrap 3内置的。只需将其添加到您的CSS:

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

为那些想要在移动设备上使用默认功能的人添加此功能。可以根据需要设置min-width: ...

@media only screen and (min-width: 1195px) {ul.nav li.dropdown:hover > ul.dropdown-menu {display: block;}ul.nav li.dropdown> ul.dropdown-menu {display: none;}}

设置display: none,这样dropdown-toggle就不会产生问题。如果您保持原样,可能会同时打开两个下拉列表。

Bootstrap版本4和5解决方案。(IE兼容)

这些是完整的解决方案,使用mouseover和Mouseleave事件以及一些屏幕宽度检查。这比纯CSS解决方案要好。

Bootstrap v5-纯JS(适用于webpack)

export class BootstrapOpenMenuHover {
/*** Constructor.*/constructor() {this.windowWidth = window.innerWidth;this.mobileBreakPoint = 991; // Put your menu break point here, when it switches to a hamburger icon.this.dropdownNavItems = document.querySelectorAll(".dropdown-toggle.nav-link");this.dropdownMenuItems = document.querySelectorAll(".dropdown-menu");
this.setEventListeners();}
/*** Set all of our event listeners.*/setEventListeners() {const _self = this;
// To be safe set the width once the dom is loaded.window.addEventListener('load',  function () {_self.windowWidth = window.innerWidth;});
// Keep track of the width in the event of a resize.window.addEventListener('resize',  function () {_self.windowWidth = window.innerWidth;});
// Bind our hover events.if (_self.dropdownNavItems !== null)  {for (let i = 0; i < _self.dropdownNavItems.length; i++) {
// On mouse enter._self.dropdownNavItems[i].addEventListener('mouseenter', function () {if (_self.windowWidth >= _self.mobileBreakPoint) {this.classList.add('show');this.ariaExpanded = true;this.dataset.bsToggle = null;
// Update the .dropdown-menuthis.nextElementSibling.classList.add('show');this.nextElementSibling.dataset.bsPopper = 'none';}});
// On mouse leave._self.dropdownNavItems[i].addEventListener('mouseleave', function () {if (_self.windowWidth >= _self.mobileBreakPoint) {this.classList.remove('show');this.ariaExpanded = false;this.dataset.bsToggle = 'dropdown';
// Update the .dropdown-menuthis.nextElementSibling.classList.remove('show');this.nextElementSibling.dataset.bsPopper = null;}});}}
// Bind events to .dropdown-menu items.if (_self.dropdownMenuItems !== null) {for (let i = 0; i < _self.dropdownMenuItems.length; i++) {// On mouse enter._self.dropdownMenuItems[i].addEventListener('mouseenter', function () {if (_self.windowWidth >= _self.mobileBreakPoint) {this.classList.add('show');this.dataset.bsPopper = 'none';
// Update the .dropdown-togglethis.previousElementSibling.classList.add('show');this.previousElementSibling.ariaExpanded = true;this.previousElementSibling.dataset.bsToggle = null;}});
// On mouse leave._self.dropdownMenuItems[i].addEventListener('mouseleave', function () {if (_self.windowWidth >= _self.mobileBreakPoint) {this.classList.remove('show');this.dataset.bsPopper = null;
// Update the .dropdown-togglethis.previousElementSibling.classList.remove('show');this.previousElementSibling.ariaExpanded = false;this.previousElementSibling.dataset.bsToggle = 'dropdown';}});}}}}
const bootstrapOpenMenuHover = new BootstrapOpenMenuHover();

Bootstrap v4解决方案

这将允许您跟踪顶级导航链接。

这是在考虑桌面和移动设备的情况下构建的。可以随意更改BREAK_POINT变量以满足您的需求:D。

jQuery

var WINDOW_WIDTH;var BREAK_POINT = 991;
(function ($) {
/** Set window width onload */WINDOW_WIDTH = $(window).width(); // Returns width of browser viewport/** Set window width if the browser is resized */$(window).resize(function () {WINDOW_WIDTH = $(window).width(); // Returns width of browser viewport});
/** Dropdown menu on mouseenter */$(".nav-item.dropdown").on('mouseenter', function () {console.log("mouseenter");if (WINDOW_WIDTH >= BREAK_POINT) {// Open up the dropdown$(this).addClass('show'); // add the class show to the li parent$(this).children('.nav-link').removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link$(this).children('.dropdown-menu').addClass('show'); // add the class show to the dropdown div sibling}});/** Dropdown menu on mouseleave */$(".nav-item.dropdown").on('mouseleave', function () {console.log("mouseleave");if (WINDOW_WIDTH >= BREAK_POINT) {// Close the dropdown$(this).removeClass('show'); // add the class show to the li parent$(this).children('.nav-link').attr('data-toggle', 'dropdown'); // remove the data-toggle attribute so we can click and follow link$(this).children('.dropdown-menu').removeClass('show'); // add the class show to the dropdown div sibling}});});

css

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

版本2的非常简单的解决方案,只有CSS。为手机和平板电脑保持相同的友好功能。

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

适用于Bootstrap V4

js:

<script>$(function() {$('.dropdown-hover').hover(function() { $(this).addClass('show'); $(this).find('[data-toggle="dropdown"]').attr('aria-expanded', true); $(this).find('.dropdown-menu').addClass('show'); },function() { $(this).removeClass('show'); $(this).find('[data-toggle="dropdown"]').attr('aria-expanded',false); $(this).find('.dropdown-menu').removeClass('show'); });});</script>

Vanilla Bootstrap 4 Dropdown超文本标记语言,除了添加dropdown hover类:

<div class="dropdown dropdown-hover"><button class="btn btn-text dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">ABOUT</button><div class="dropdown-menu" aria-labelledby="dropdownMenuButton"><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>

如果您不想通过使用. dropdown hover类有选择地启用hover功能,那么只需将jQuery选择器从. dropdown hover更改为. dropdown。

Bootstrap 4,2019

我读了很多这些答案,但最终我自己做了,因为这不是我需要的。

我有Bootstrap 4,想要保持点击+悬停功能。此外,我想仅在具有额外类“. open-on-hover”的下拉菜单上启用它。

我还想保留Bootstrap的JQuery,当它靠近页面边缘时将下拉列表定位。所以我们不仅仅想做“显示:阻止”。我们想要完整的Bootstrap工作方式。所以我只是触发单击。

逻辑是“如果它是一个鼠标,那么打开它,如果它是一个鼠标,那么隐藏它,如果它是打开的”

/*** Open Bootstrap 4 dropdown on hover*/$(document).on('mouseenter mouseleave', '.dropdown.open-on-hover', function(e){let toggler = $(this).find('[data-toggle="dropdown"]').first();
if(e.type === 'mouseenter') {$(toggler).trigger('click', 'open');} else if ($(this).children('.dropdown-menu.show').length) {$(toggler).trigger('click', 'close');}});

的html

<div class="dropdown open-on-hover"><div class="btn" data-toggle="dropdown">Hover or click me</div><div class="dropdown-menu"><a class="dropdown-item">Item 1</a><a class="dropdown-item">Item 2</a></div></div>

这也可以做到这一点。

$('.dropdown').on('mouseover',function(){$(this).find('.dropdown-menu').show();});$('.dropdown').on('mouseleave',function(){$(this).find('.dropdown-menu').hide();});

如果下拉列表在悬停元素之间有间隙,下拉列表将立即关闭,如图所示

元素被清除后立即下拉隐藏

为了防止这种行为,您可以为100 ms的事件添加超时

let dropdownTimer;$('.dropdown').on('mouseover', () => {clearTimeout(dropdownTimer)$(this).find('.dropdown-menu').show();});$('.dropdown').on('mouseleave', () =>{dropdownTimer = setTimeout(() => {$(this).find('.dropdown-menu').hide();}, 100)});

在设定的超时时间内保持打开的下拉列表