Gostaria que meu menu Bootstrap fosse suspenso automaticamente ao passar o mouse, em vez de precisar clicar no título do menu. Eu também gostaria de perder as pequenas flechas ao lado dos títulos do menu.
Gostaria que meu menu Bootstrap fosse suspenso automaticamente ao passar o mouse, em vez de precisar clicar no título do menu. Eu também gostaria de perder as pequenas flechas ao lado dos títulos do menu.
Respostas:
Criei um menu suspenso puro em foco, com base na mais recente (v2.0.2) estrutura de Bootstrap que oferece suporte a vários submenus e pensei em publicá-la para futuros usuários:
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"
para que apenas pairasse, não clique acionasse o menu. Observe que, quando você usa estilos responsivos, os menus ainda são arrastados para o pequeno botão no canto superior direito, que ainda é acionado por um clique. Muito obrigado!
@media (min-width: 768px) {.dropdown-menu li:hover .sub-menu {visibility: visible;}}
e@media (min-width: 768px) {.dropdown:hover .dropdown-menu {display: block;}}
Para que o menu apareça automaticamente ao passar o mouse, isso pode ser feito usando CSS básico. Você precisa definir o seletor para a opção de menu oculto e configurá-lo para exibir como bloco quando a li
tag apropriada for colocada sobre o mouse. Tomando o exemplo da página de inicialização do twitter, o seletor seria o seguinte:
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
No entanto, se você estiver usando os recursos responsivos do Bootstrap, não desejará essa funcionalidade em uma barra de navegação recolhida (em telas menores). Para evitar isso, envolva o código acima em uma consulta de mídia:
@media (min-width: 979px) {
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
}
Para ocultar a seta (cursor), isso é feito de maneiras diferentes, dependendo de você estar usando o Twitter Bootstrap versão 2 e inferior ou versão 3:
Bootstrap 3
Para remover o sinal de intercalação na versão 3, você só precisa remover o HTML <b class="caret"></b>
do .dropdown-toggle
elemento anchor:
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Dropdown
<b class="caret"></b> <-- remove this line
</a>
Bootstrap 2 e inferior
Para remover o sinal de intercalação na versão 2, você precisa de um pouco mais de conhecimento sobre CSS e sugiro examinar como o :after
pseudo elemento funciona com mais detalhes. Para você começar a entender, direcionar e remover as setas no exemplo de inicialização do twitter, use o seguinte seletor e código de CSS:
a.menu:after, .dropdown-toggle:after {
content: none;
}
Isso funcionará a seu favor se você examinar mais detalhadamente como isso funciona e não apenas usar as respostas que eu lhe dei.
Agradecemos a @CocaAkat por salientar que estávamos perdendo o combinador filho ">" para impedir que submenus sejam mostrados no cursor principal
margin: 0;
, caso contrário, a margem de 1 px acima .dropdown-menu
causa comportamento de buggy.
data-toggle="dropdown"
atributo.
Além da resposta de "My Head Hurts" (que foi ótimo):
ul.nav li.dropdown:hover ul.dropdown-menu{
display: block;
}
Existem dois problemas remanescentes:
A solução para (1) está removendo os elementos "class" e "data-toggle" do link de navegação
<a href="#">
Dropdown
<b class="caret"></b>
</a>
Isso também permite que você crie um link para sua página pai - o que não era possível com a implementação padrão. Você pode simplesmente substituir o "#" por qualquer página que você queira enviar ao usuário.
A solução para (2) está removendo a margem superior no seletor de menu .dropdown
.navbar .dropdown-menu {
margin-top: 0px;
}
data-toggle="dropdown"
atributo, que parecia funcionar.
.nav-pills .dropdown-menu { margin-top: 0px; }
Eu usei um pouco de 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); }); });
: Quando o submenu é pairar parada fadeOut
Existem muitas soluções realmente boas aqui. Mas eu pensei que iria em frente e colocaria o meu aqui como outra alternativa. É apenas um snippet simples do jQuery que faz da maneira que o bootstrap faria se suportasse pairar para menus suspensos em vez de apenas clicar. Eu só testei isso com a versão 3, então não sei se funcionaria com a versão 2. Salve-o como um trecho no seu editor e faça-o com o toque de uma tecla.
<script>
$(function() {
$(".dropdown").hover(
function(){ $(this).addClass('open') },
function(){ $(this).removeClass('open') }
);
});
</script>
Basicamente, está apenas dizendo que quando você passa o mouse na classe suspensa, ela adiciona a classe aberta a ela. Então simplesmente funciona. Quando você para de pairar no li pai com a classe suspensa ou nos ul / li filhos, ele remove a classe aberta. Obviamente, essa é apenas uma das muitas soluções, e você pode adicioná-lo para fazê-lo funcionar apenas em instâncias específicas de .dropdown. Ou adicione uma transição para pai ou filho.
Se você possui um elemento com uma dropdown
classe como esta (por exemplo):
<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>
Em seguida, você pode fazer com que o menu suspenso seja suspenso automaticamente ao passar o mouse, em vez de precisar clicar no título, usando este trecho de código 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>
Esta resposta foi baseada na resposta do @Michael , fiz algumas alterações e adicionei algumas adições para que o menu suspenso funcione corretamente
[Update] O plugin está no GitHub e estou trabalhando em algumas melhorias (como usar apenas com atributos de dados (não é necessário JS)) .Deixei o código abaixo, mas não é o mesmo que o GitHub.
Gostei da versão puramente CSS, mas é bom ter um atraso antes de fechar, pois geralmente é uma melhor experiência do usuário (ou seja, não é punida por um deslizamento de mouse que fica 1 px fora da lista suspensa, etc.), e conforme mencionado nos comentários , há 1px de margem com a qual você precisa lidar ou, às vezes, a navegação fecha inesperadamente quando você está indo para a lista suspensa a partir do botão original etc.
Criei um pequeno plugin rápido que usei em alguns sites e funcionou muito bem. Cada item de navegação é tratado de forma independente, para que eles tenham seus próprios temporizadores de atraso, etc.
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);
});
});
};
O delay
parâmetro é bastante auto-explicativo e oinstantlyCloseOthers
fechará instantaneamente todos os outros menus suspensos abertos quando você passar o mouse sobre um novo.
Não é CSS puro, mas espero que ajude alguém a esta hora tardia (ou seja, esse é um tópico antigo).
Se você quiser, poderá ver os diferentes processos pelos quais passei (em uma discussão sobre o #concrete5
IRC) para fazê-lo funcionar através das diferentes etapas nesta lista: https://gist.github.com/3876924
A abordagem do padrão de plug-in é muito mais limpa para suportar temporizadores individuais, etc.
Ainda melhor com o 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'); });
para que o submenu não seja exibido em foco.
Só quero acrescentar que, se você tiver vários menus suspensos (como eu), escreva:
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
E vai funcionar corretamente.
margin: 2px 0 0;
que significava que um lento mouseEnter de cima escondeu o menu prematuramente. ul.dropdown-menu{ margin-top: 0; }
Na minha opinião, a melhor maneira é assim:
;(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);
Exemplo de marcação:
<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>
A melhor maneira de fazer isso é acionar o evento de clique do Bootstrap com um cursor do mouse. Dessa forma, ele ainda deve permanecer amigável ao dispositivo de toque.
$('.dropdown').hover(function(){
$('.dropdown-toggle', this).trigger('click');
});
Eu consegui da seguinte maneira:
$('ul.nav li.dropdown').hover(function(){
$(this).children('ul.dropdown-menu').slideDown();
}, function(){
$(this).children('ul.dropdown-menu').slideUp();
});
Espero que isso ajude alguém...
Também foi adicionado margin-top: 0 para redefinir a margem de bootstrap css para .dropdown-menu, para que a lista de menus não desapareça quando o usuário passar lentamente do menu suspenso para a lista de menus.
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
.nav .dropdown-menu {
margin-top: 0;
}
Publiquei um plug-in adequado para a funcionalidade suspensa de inicialização do Bootstrap 3, na qual você pode definir o que acontece ao clicar nodropdown-toggle
elemento (o clique pode ser desativado):
https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
Eu tive problemas com todas as soluções existentes anteriormente. Os CSS simples não estão usando a .open
classe no .dropdown
, portanto, não haverá feedback sobre o elemento de alternância quando o menu suspenso estiver visível.
Os js estão interferindo ao clicar em .dropdown-toggle
; portanto, o menu suspenso aparece ao passar o mouse e depois o oculta ao clicar em um menu suspenso aberto, e sair do mouse aciona o menu suspenso para que apareça novamente. Algumas das soluções js estão quebrando a compatibilidade com o iOS, alguns plugins não estão funcionando em navegadores de desktop modernos que suportam os eventos de toque.
Foi por isso que criei o plug-in Bootstrap Dropdown Hover, que evita todos esses problemas usando apenas a API javascript Bootstrap padrão, sem qualquer invasão . Até os atributos Aria estão funcionando bem com este plugin.
bootstrap-dropdown-hover
, porque parece fazer o trabalho e mais compacto. Estou construindo um local de pouso com a barra de navegação do lado esquerdo.
Use este código para abrir o submenu ao passar o mouse (somente na área de trabalho):
$('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','');
}
});
E se você quiser que o menu do primeiro nível seja clicável, mesmo no celular, adicione este:
$('.dropdown-toggle').click(function() {
if ($(this).next('.dropdown-menu').is(':visible')) {
window.location = $(this).attr('href');
}
});
O submenu (menu suspenso) será aberto com o mouse sobre a área de trabalho e com o clique / toque no celular e tablet. Depois que o submenu foi aberto, um segundo clique permitirá que você abra o link. Graças ao if ($(window).width() > 767)
, o submenu terá a largura de tela cheia no celular.
$('.dropdown').hover(function(e){$(this).addClass('open')})
Isso deve ocultar as listas suspensas e seus pontos de intercalação, se forem menores que um tablet.
@media (max-width: 768px) {
.navbar ul.dropdown-menu, .navbar li.dropdown b.caret {
display: none;
}
}
A solução jQuery é boa, mas precisará lidar com eventos de clique (para celular ou tablet), pois o hover não funcionará corretamente ... Talvez seja possível detectar alguma redimensionamento de janela?
A resposta de Andres Ilich parece funcionar bem, mas deve estar envolvida em uma consulta de mídia:
@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;
}
}
A solução muito simples para a versão 2, apenas CSS. Mantém a mesma funcionalidade amigável para celular e tablet.
@media (min-width: 980px) {
.dropdown:hover .dropdown-menu {
display: block;
}
}
Substitua bootstrap.js por este script.
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') })
});
});
Aqui está minha técnica que adiciona um pequeno atraso antes que o menu seja fechado após você parar de pairar no menu ou no botão de alternância. O <button>
que você normalmente clicaria para exibir o menu de navegação é #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);
});
Para melhorar a resposta de Sudharshan, envolvo isso em uma consulta de mídia para evitar o foco quando as larguras de exibição do XS ...
@media (min-width:768px)
{
ul.nav li.dropdown:hover > ul.dropdown-menu {
display: block;
}
.nav .dropdown-menu {
margin-top: 0;
}
}
Além disso, o cursor na marcação não é necessário, apenas a classe suspensa para o li .
Então você tem este código:
<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>
Normalmente, ele funciona em um evento de clique e você deseja que ele funcione em um evento de foco. Isso é muito simples, basta usar este código 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();
})
})
})
Isso funciona muito bem e aqui está a explicação: temos um botão e um menu. Quando passamos o mouse, exibimos o menu e, quando passamos o mouse, ocultamos o menu após 100 ms. Se você se pergunta por que eu uso isso, é porque você precisa de tempo para arrastar o cursor do botão sobre o menu. Quando você está no menu, a hora é redefinida e você pode ficar lá quantas vezes quiser. Quando você sai do menu, ocultaremos o menu instantaneamente sem tempo limite.
Eu usei esse código em muitos projetos; se você encontrar algum problema com ele, sinta-se à vontade para me fazer perguntas.