我想让我的Bootstrap菜单在悬停时自动下拉,而不是必须单击菜单标题。我也想丢掉菜单标题旁边的小箭头。
我想让我的Bootstrap菜单在悬停时自动下拉,而不是必须单击菜单标题。我也想丢掉菜单标题旁边的小箭头。
Answers:
我基于最新的(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>
class="dropdown-toggle" data-toggle="dropdown"
了菜单,以便仅将鼠标悬停而不单击即可触发菜单。请注意,当您使用自适应样式时,菜单仍然会扫入右上角的小按钮,该按钮仍然是单击触发的。太谢谢了!
@media (min-width: 768px) {.dropdown-menu li:hover .sub-menu {visibility: visible;}}
和@media (min-width: 768px) {.dropdown:hover .dropdown-menu {display: block;}}
要使菜单自动悬停,可以使用基本CSS来实现。您需要将选择器设计为隐藏菜单选项,然后将其li
悬停在适当的标签上时将其设置为显示为块。以twitter引导页面为例,选择器如下:
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:
引导程序3
要删除版本3中的插入符号,您只需<b class="caret"></b>
要从.dropdown-toggle
anchor元素中删除HTML :
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Dropdown
<b class="caret"></b> <-- remove this line
</a>
Bootstrap 2及更低
要删除版本2中的插入符号,您需要对CSS有更多的了解,我建议您:after
更详细地了解伪元素的工作方式。为了使您开始理解方式,在twitter引导程序示例中定位和删除箭头,可以使用以下CSS选择器和代码:
a.menu:after, .dropdown-toggle:after {
content: none;
}
如果您进一步研究这些工作原理,而不仅仅是使用我给您的答案,它将对您有利。
感谢@CocaAkat指出我们缺少“>”子组合器,以防止子菜单显示在父悬停中
margin: 0;
,否则上面的1px边距.dropdown-menu
会导致越野车行为。
data-toggle="dropdown"
属性。
除了“我的头疼”的答案(很棒)之外:
ul.nav li.dropdown:hover ul.dropdown-menu{
display: block;
}
有两个长期存在的问题:
(1)的解决方案是从导航链接中删除“类”和“数据切换”元素
<a href="#">
Dropdown
<b class="caret"></b>
</a>
这也使您能够创建到父页面的链接-使用默认实现是不可能的。您可以将“#”替换为要发送给用户的任何页面。
(2)的解决方案是删除.dropdown-menu选择器上的margin-top
.navbar .dropdown-menu {
margin-top: 0px;
}
data-toggle="dropdown"
属性,该属性似乎起作用了。
.nav-pills .dropdown-menu { margin-top: 0px; }
我使用了一些jQuery:
// Add hover effect to menus
jQuery('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();
});
$('ul.nav li.dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut().hover(function() { $(this).stop(true, true); }); });
:当子菜单悬停时,请停止fadeOut
这里有很多非常好的解决方案。但是我想我会继续做下去,把我的东西放在这里作为另一种选择。这只是一个简单的jQuery代码段,如果它支持将鼠标悬停在下拉菜单上而不是单击鼠标,则采用Bootstrap的方式进行。我仅在版本3中进行了测试,因此我不知道它是否可以在版本2中使用。将其另存为编辑器中的代码段,并一按即可。
<script>
$(function() {
$(".dropdown").hover(
function(){ $(this).addClass('open') },
function(){ $(this).removeClass('open') }
);
});
</script>
基本上,这只是说,当您将鼠标悬停在下拉菜单上时,它将向其中添加开放类。然后就可以了。当您停止在具有下拉类的父级li或子级ul / li的子级li上徘徊时,它将删除开放类。显然,这只是许多解决方案之一,您可以对其进行添加以使其仅在特定的.dropdown实例上运行。或向父级或子级添加过渡。
如果您的元素具有这样的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答案,我进行了一些更改并添加了一些其他内容,以使下拉菜单正常工作
[更新]该插件位于GitHub上,我正在做一些改进(例如仅用于数据属性(无需JS)。我将代码保留在下面,但与GitHub上的不一样。
我喜欢纯粹的CSS版本,但是在关闭之前会有延迟是很高兴的,因为通常这是更好的用户体验(例如,不会因为鼠标滑动超出下拉菜单1 px而受到惩罚),并且如评论中所述,那么当您从原始按钮移至下拉菜单时,您必须处理1px的页边空白,或者有时导航会意外关闭。
我创建了一个快速的小插件,并在几个站点上使用过,效果很好。每个导航项都是独立处理的,因此它们有自己的延迟计时器等。
JS
// outside the scope of the jQuery plugin to
// keep track of all dropdowns
var $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
插件模式方法更清洁,可以支持单个计时器等。
使用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');
});
jQuery('ul.nav li.dropdown').hover(function() { jQuery(this).closest('.dropdown-menu').stop(true, true).show(); jQuery(this).addClass('open'); }, function() { jQuery(this).closest('.dropdown-menu').stop(true, true).hide(); jQuery(this).removeClass('open'); });
所以子菜单不会在悬停时显示。
我认为最好的方法是这样的:
;(function($, window, undefined) {
// Outside the scope of the jQuery plugin to
// keep track of all dropdowns
var $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 dropdown
if(!$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>
最好的方法是通过悬停触发Bootstrap的click事件。这样,它仍应保持对触摸设备的友好。
$('.dropdown').hover(function(){
$('.dropdown-toggle', this).trigger('click');
});
只需添加一下,如果您有多个下拉菜单(就像我一样),您应该写:
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
并且它将正常工作。
margin: 2px 0 0;
意味着从上面缓慢的mouseEnter会过早隐藏菜单。 ul.dropdown-menu{ margin-top: 0; }
我已经按如下方式进行管理:
$('ul.nav li.dropdown').hover(function(){
$(this).children('ul.dropdown-menu').slideDown();
}, function(){
$(this).children('ul.dropdown-menu').slideUp();
});
我希望这可以帮助别人...
还添加了margin-top:0来重置.dropdown-menu的引导CSS边距,因此当用户从下拉菜单缓慢移至菜单列表时,菜单列表不会消失。
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
.nav .dropdown-menu {
margin-top: 0;
}
我已经发布了适用于Bootstrap 3下拉悬停功能的适当插件,您甚至可以在其中定义单击dropdown-toggle
元素时发生的事情(可以禁用单击):
https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
我以前所有现有的解决方案都遇到了问题。简单的CSS不在上使用.open
类.dropdown
,因此当下拉列表可见时,下拉切换元素将没有反馈。
js干扰了单击.dropdown-toggle
,因此该下拉菜单会在悬停时显示,然后在单击打开的下拉菜单时将其隐藏,然后移开鼠标会触发该下拉菜单再次显示。一些js解决方案打破了iOS的兼容性,一些插件在支持触摸事件的现代桌面浏览器上无法正常工作。
这就是为什么我制作了Bootstrap Dropdown Hover 插件的原因,该插件通过仅使用标准的Bootstrap javascript API来避免所有这些问题,而没有任何hack。甚至Aria属性也可以使用此插件正常工作。
bootstrap-dropdown-hover
,因为它似乎可以完成工作并且更加紧凑。我正在用左侧导航栏构建一个着陆点。
使用以下代码在鼠标悬停时打开子菜单(仅限桌面):
$('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)
,该子菜单将在移动设备上显示全屏宽度。
jQuery解决方案很好,但是由于悬停无法正常工作,因此需要处理点击事件(针对移动设备或平板电脑)...也许可以进行一些窗口大小调整吗?
安德列斯·伊利希(Andres Ilich)的答案似乎不错,但应将其包装在媒体查询中:
@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;
}
}
版本2的非常简单的解决方案,仅CSS。保持与手机和平板电脑相同的友好功能。
@media (min-width: 980px) {
.dropdown:hover .dropdown-menu {
display: block;
}
}
使用此脚本覆盖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') })
});
});
这是我的技术,在您停止在菜单或切换按钮上停止悬停之后,在关闭菜单之前会稍有延迟。在<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);
});
为了增强Sudharshan的回答,我将其包装在媒体查询中,以防止在XS显示器宽度上悬停...
@media (min-width:768px)
{
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
.nav .dropdown-menu {
margin-top: 0;
}
}
另外,在标记插入符号不是必需的,只是在下拉菜单的类里。
因此,您有以下代码:
<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>
通常,它适用于click事件,而您希望它适用于悬停事件。这非常简单,只需使用以下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 ms之后隐藏菜单。如果您想知道为什么要使用它,是因为您需要时间将光标从菜单上的按钮拖动。当您在菜单上时,时间将重置,您可以在此处停留任意多的时间。当您退出菜单时,我们将立即隐藏菜单,而不会发生任何超时。
我在许多项目中都使用过此代码,如果您在使用它时遇到任何问题,请随时向我提问。