Bootstrap带悬停效果的下拉菜单

229

好的,我需要的内容非常简单。

我设置了一个带有下拉菜单的导航栏(使用class="dropdown-toggle" data-toggle="dropdown"),它可以正常工作。

问题是它是"onClick"触发的,但我更喜欢它在"onHover"时触发。

有没有内置的方法来实现这个效果?


1
请查看我最新发布的适当插件,它可以防止以下CSS和js解决方案的问题:https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover - István Ujj-Mészáros
26个回答

455
最简单的解决方案是使用CSS。添加类似以下内容的代码:
.dropdown:hover .dropdown-menu {
    display: block;
    margin-top: 0; /* remove the gap so it doesn't close */
}

JSFiddle


3
比长篇的“完整构建”解决方案要好得多。只需添加此内容,即可在悬停时使默认的“单击”下拉菜单起作用,无需额外更改。 - iamface
67
这会与内置的可折叠移动菜单产生冲突,因此您应该将其包裹在一个断点@media (min-width:480px)中。 - Billy Shih
9
值得一提的是:如果您有一个带有父子关系的下拉菜单,例如在WordPress主题中,您需要删除data-toggle属性以使父项可点击......但要注意在移动屏幕上可能会出现的副作用。 - Ken Prince
4
有没有一种简单的方法可以在点击时禁用显示,并仅保留悬停行为? - Micer
7
@Micer 使用此 CSS 方案可以很好地实现悬停效果,但如果您还单击了该项,则在鼠标移开该项后下拉菜单仍然保持显示。这是因为单击会在“悬停”下拉菜单下方打开第二个下拉菜单。要解决此问题,请从子<a>元素中删除 data-toggle =“dropdown” 属性,这将防止单击打开重复的下拉菜单。 - Xcalibur
显示剩余10条评论

73

最好的方法是使用悬停触发Bootstrap的点击事件。这样,它仍然可以保持对触摸设备的友好性。

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

2
如果您有多个下拉级别,则会失败。 - Connie DeCinko
1
无法使用父链接。 - JBC
有没有办法在下拉菜单关闭后删除Active类? - brainvision
下拉元素和菜单之间存在一个像素间隙,可能会导致菜单在跨越时有时会隐藏,除非您很快。 - Matt
1
使用多个下拉菜单需要一些“最近”的过滤。 - err
对我来说,这也会触发菜单项的焦点,看起来很糟糕。因此,我添加了 .blur()$('.dropdown-toggle',this).trigger('click')。blur(); - Filipe

65

您可以使用jQuery的hover函数。

当鼠标进入下拉菜单时,只需添加类open,并在鼠标离开时删除该类。

这是我的代码:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});

12
在我看来,这比被接受的答案好得多。这可以保持所有引导逻辑和样式不变。尽管我建议使用第二个回调函数,并明确使用removeClass和addClass来防止在单击按钮时出现一些奇怪的行为(即当您离开按钮时它会打开,当您进入它时它会关闭)。 - Bastiaan Linders
7
我也认为这是最好的答案。要使其与Bootstrap 4菜单一起使用,我必须使用show而不是open,还要包括dropdown-menu$('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(对排版问题表示抱歉)。 - Robin Zimmermann
如果有两个下拉菜单,请勿使用此方法。悬停在任何一个下拉菜单上都将显示两个子菜单。 - Juan Antonio Tubío

29

使用jQuery的一种简单方法如下:

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

我喜欢平滑的过渡效果,但它会导致所有级别的菜单都展开,而不仅仅是第一级。我不希望在鼠标悬停在父级菜单上之前出现第二级菜单。 - Connie DeCinko
1

要仅获取第一级,请添加.first()

$(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);
- flydev

13

CSS在点击时会疯狂跳动。这是我正在使用的代码,它在移动视图中也不会改变任何内容。

$('.dropdown').mouseenter(function(){
    if(!$('.navbar-toggle').is(':visible')) { // disable for mobile view
        if(!$(this).hasClass('open')) { // Keeps it open when hover it again
            $('.dropdown-toggle', this).trigger('click');
        }
    }
});

1
一个美丽的问题!谢谢!CSS的替代方案在Bootstrap 3及以后的版本中不起作用。 - Pedro Ferreira
1
谢谢!最终选择了以下代码: $('.dropdown').mouseenter(function() { if(!$('.navbar-toggle').is(':visible')) { $(this).addClass('open'); } }); $('.dropdown').mouseleave(function() { if(!$('.navbar-toggle').is(':visible')) { $(this).removeClass('open'); } }); - BanAnanas

6

所以你有这段代码:

<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毫秒后消失。如果你想知道为什么要这样做,那是因为你需要时间将光标从按钮移到菜单上。当你在菜单上时,时间会重置,你可以在那里停留任意长的时间。当你退出菜单时,我们会立即隐藏菜单,没有任何延迟。

我在许多项目中都使用了这个代码,如果你使用它遇到任何问题,请随时向我提问。


这段代码在Bootstrap v3上存在很多问题。1)如果有多个下拉菜单,当悬停在任何一个上时,所有下拉菜单都会显示。2)在小屏幕上,悬停会以奇怪的方式显示下拉菜单。 - KayakinKoder

6

请投票关闭重复问题,而不是回答它们。 - undefined

6

4
这将帮助你创建自己的bootstrap hover类:
CSS:
/* Hover dropdown */
.hover_drop_down.input-group-btn ul.dropdown-menu{margin-top: 0px;}/*To avoid unwanted close*/
.hover_drop_down.btn-group ul.dropdown-menu{margin-top:2px;}/*To avoid unwanted close*/
.hover_drop_down:hover ul.dropdown-menu{
   display: block;
}

边距是用来避免不必要的紧密排列的,但它们是可选的。

HTML:

<div class="btn-group hover_drop_down">
  <button type="button" class="btn btn-default" data-toggle="dropdown"></button>
  <ul class="dropdown-menu" role="menu">
    ...
  </ul>
</div>

如果您想删除“onclick”打开方式,请不要忘记删除按钮属性data-toggle="dropdown",并且在附加下拉菜单时也会起作用。


4

使用适当的插件更新

我发布了一个适当的插件,用于下拉悬停功能,您甚至可以定义在单击dropdown-toggle元素时发生什么:

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


为什么要制作它,当已经有许多解决方案了?

我遇到了所有先前存在的解决方案的问题。简单的CSS解决方案没有在.dropdown上使用.open类,因此当下拉菜单可见时,下拉切换元素不会有任何反馈。

js解决方案干扰了单击.dropdown-toggle,因此当悬停时下拉菜单显示出来,然后在单击打开的下拉菜单时隐藏它,并且移动鼠标会触发下拉菜单再次显示出来。一些js解决方案破坏了iOS兼容性,一些插件在支持触摸事件的现代桌面浏览器上无法工作。

这就是为什么我制作了Bootstrap Dropdown Hover插件,它通过仅使用标准的Bootstrap JavaScript API而没有任何黑客来防止所有这些问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接