;(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);
// 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);
});
});
};
30 回答
只想添加,如果您有多个下拉菜单(就像我一样),您应该写:
它会正常工作 .
执行此操作的最佳方法是使用悬停触发Bootstrap的单击事件 . 这样,它应该仍然保持触摸设备友好 .
除了“My Head Hurts”(这很棒)的回答:
有两个挥之不去的问题:
点击下拉链接将打开下拉菜单 . 除非用户点击其他地方,否则它将保持打开状态,或者将其悬停在其上,从而创建一个尴尬的UI .
下拉链接和下拉菜单之间有1px的余量 . 如果您在下拉菜单和下拉菜单之间缓慢移动,则会导致下拉菜单变为隐藏状态 .
(1)的解决方案是从导航链接中删除“class”和“data-toggle”元素
这也使您能够创建指向父页面的链接 - 这是默认实现无法实现的 . 您只需将“#”替换为您要发送给用户的任何页面即可 .
(2)的解决方案是删除.dropdown菜单选择器上的margin-top
为了增强Sudharshan's answer,我将其包装在媒体查询中,以防止在XS显示宽度时悬停...
此外,标记中的插入符号不是必需的,只是 li 的 dropdown 类 .
这里有很多非常好的解决方案 . 但我认为我会继续把我的作为另一种选择 . 这只是一个简单的jQuery代码片段,如果它支持将鼠标悬停在下拉菜单而不是单击,那么就像引导程序一样 . 我只用版本3对它进行了测试,所以我不知道它是否适用于版本2.将它保存为编辑器中的一个片段,然后按一下键 .
基本上,它只是说当你将鼠标悬停在下拉列表上时,它会向它添加开放类 . 然后就行了 . 当您停止使用下拉类或子ul / li徘徊在父li上时,它将删除打开的类 . 显然,这只是众多解决方案中的一种,您可以添加它以使其仅适用于.dropdown的特定实例 . 或者向父母或孩子添加转换 .
这适用于WordPress Bootstrap:
我按如下方式管理它:
我希望这可以帮助别人...
对于插入符...我没有看到任何一个指定简单的CSS完全阻止插入符号 .
干得好:
这将隐藏上升的
这可能是一个愚蠢的想法,但只需删除指向下方的箭头,您就可以删除
尽管如此......这对于指向一个人没有任何帮助 .
jQuery解决方案很好,但它需要处理点击事件(对于移动设备或平板电脑),因为悬停将无法正常工作...可能会做一些窗口重新大小检测?
Andres Ilich的答案似乎运作良好,但它应该包含在媒体查询中:
在我看来,最好的方法是这样的:
样本标记:
这是我的技术,在您停止悬停在菜单或切换按钮上之后,在菜单关闭之前会稍微延迟 . 您通常单击以显示导航菜单的
<button>
是#nav_dropdown
.我基于最新的(v2.0.2)Bootstrap框架创建了一个纯粹的悬停下拉菜单,该框架支持多个子菜单,并且我认为我会为将来的用户发布它:
Demo
只需在三行代码中自定义CSS样式即可
我使用了一些jQuery:
使用jQuery更好:
[Update] 该插件在GitHub上,我正在进行一些改进(比如仅使用数据属性(不需要JS) . 我've leaving the code in below, but it'与GitHub上的内容不同 .
我喜欢纯粹的CSS版本,但是在它关闭之前有一个延迟是很好的,因为它通常是一个更好的用户体验(即不会因为在下拉列表外1 px的鼠标滑动而受到惩罚等),并且如评论中所述,你需要处理1px的保证金,或者当你从原始按钮移动到下拉菜单时,导航器有时意外关闭等 .
我创建了一个快速的小插件,我已经在几个网站上使用它并且它工作得很好 . 每个导航项都是独立处理的,因此它们有自己的延迟计时器等 .
JS
delay
参数非常自我解释,当您将鼠标悬停在新的下拉列表时,instantlyCloseOthers
将立即关闭所有其他打开的下拉列表 .不是纯粹的CSS,但希望能在这么晚的时候帮助其他人(即这是一个旧线程) .
如果你愿意,你可以看到我经历的不同过程(在
#concrete5
IRC的讨论中)通过这个要点中的不同步骤使其工作:https://gist.github.com/3876924插件模式方法更加清晰,可以支持个人计时器等 .
请参阅blog post更多 .
这对我有用:
所以你有这个代码:
通常它适用于单击事件,您希望它适用于悬停事件 . 这很简单,只需使用这个JavaScript / jQuery代码:
这非常有效,这里有解释:我们有一个按钮和一个菜单 . 当我们悬停按钮时,我们会显示菜单,当我们鼠标拖出按钮时,我们会在100毫秒后隐藏菜单 . 如果你想知道为什么我使用它,是因为你需要时间从菜单上的按钮拖动光标 . 当您在菜单上时,时间被重置,您可以在任意时间停留在那里 . 当您退出菜单时,我们将立即隐藏菜单而不会超时 .
我在很多项目中都使用过这段代码,如果你遇到任何问题,请随时问我问题 .
您可以使用默认的
$().dropdown('toggle')
方法在悬停时切换下拉菜单:如果你有一个像这样的
dropdown
类的元素(例如):然后你可以让鼠标悬停在下拉菜单上,而不是必须点击它的 Headers ,使用这段jQuery代码:
Here is a demo
这个答案依赖于@Michael answer,我做了一些更改并添加了一些补充以使下拉菜单正常工作
使用此代码在mousehover上打开子菜单(仅限桌面):
如果您希望第一级菜单可以点击,即使在移动设备上也可以添加:
子菜单(下拉菜单)将通过鼠标悬停在桌面上打开,并通过手机和平板电脑上的点击/触摸来打开 . 子菜单打开后,第二次单击将允许您打开链接 . 感谢
if ($(window).width() > 767)
,子菜单将采用移动设备的全屏宽度 .如果它们小于平板电脑,这应该隐藏下拉和它们的插入物 .
这是内置于Bootstrap 3.只需将其添加到您的CSS:
我已经为Bootstrap 3下拉悬停功能发布了 proper plugin ,您甚至可以在其中定义单击
dropdown-toggle
元素时发生的情况(可以禁用单击):https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
为什么我已经有很多解决方案了?
我遇到了所有以前存在的解决方案的问题 . 简单的CSS没有使用
.dropdown
上的.open
类,因此当下拉列表可见时,下拉切换元素将不会有任何反馈 .js正在干扰点击
.dropdown-toggle
,因此下拉列表会显示下拉列表,然后在点击打开的下拉列表时隐藏它,移出鼠标会触发下拉列表再次显示 . 一些js解决方案破坏了iOS兼容性,一些插件不适用于支持触摸事件的现代桌面浏览器 .这就是为什么我通过 using only the standard Bootstrap javascript API, without any hack 制作了Bootstrap Dropdown Hover plugin 来防止所有这些问题 . 即使是Aria属性也能正常使用这个插件 .
使用此脚本覆盖bootstrap.js .
还添加了margin-top:0来重置.dropdown-menu的bootstrap css边距,这样当用户从下拉菜单慢慢地徘徊到菜单列表时,菜单列表不会消失 .
要使菜单在悬停时自动停止,那么可以使用基本CSS实现 . 您需要将选择器设置为隐藏菜单选项,然后将其设置为在相应的
li
标记悬停时显示为块 . 以twitter bootstrap页面为例,选择器如下:但是,如果您使用的是Bootstrap的响应功能,则在折叠的导航栏上(在较小的屏幕上)不需要此功能 . 要避免这种情况,请将以上代码包装在媒体查询中:
要隐藏箭头(插入符号),这取决于您使用的是Twitter Bootstrap版本2及更低版本还是版本3:
Bootstrap 3
要删除版本3中的插入符号,只需从
.dropdown-toggle
anchor元素中删除HTML<b class="caret"></b>
:Bootstrap 2 & lower
要删除版本2中的插入符号,您需要更深入地了解CSS,我建议查看
:after
伪元素如何更详细地工作 . 为了让您开始理解,定位和删除twitter bootstrap示例中的箭头,您将使用以下CSS选择器和代码:如果你进一步研究这些工作的方式而不仅仅是使用我给你的答案,它将对你有利 .
Thanks to @CocaAkat for pointing out that we were missing the ">" child combinator to prevent sub menus being shown on the parent hover