Como fazer o menu suspenso do Twitter Bootstrap passar o mouse em vez de clicar

1181

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.

vacilar
fonte
9
Existe uma solução para isso, então a resposta da mikko está correta, mas agora é abordada com um plugin especificamente para essa situação. bootstrap-hover-dropdown
HenryW 4/04
2
Veja meu plug-in adequado recém-publicado, que evita os problemas das soluções CSS e js abaixo, e funciona bem no iOS e em navegadores de desktop modernos com eventos de toque. Mesmo os atributos aria estão trabalhando bem com isso: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Mészáros ujj-
Eu fiz uma lista suspensa CSS3 pura com uma inicialização navbar verificá-la no CodePen Pure CSS3 suspensa
Gothburz
18
Pense duas vezes se você realmente precisa? O Bootstrap está sendo usado para sites adaptáveis. Isso significa que eles também serão usados ​​em dispositivos com controles por toque. É por isso que é projetado dessa maneira. Não há "pairar" nas telas de toque.
Serj.by
Possível duplicata do Bootstrap Dropdown com Hover #
slugster

Respostas:

590

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>

Demo

Andres Ilich
fonte
54
é uma decisão de design em inicialização para não abrir os menus suspensos em caso de foco ...
caarlos0
18
tão bom! Também removi 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!
PTIM
11
Para evitar a auto cair em dispositivos menores (como telefones) e aonly permitir que ele a partir de um min-largura de, por exemplo 768px fazer @media (min-width: 768px) {.dropdown-menu li:hover .sub-menu {visibility: visible;}}e@media (min-width: 768px) {.dropdown:hover .dropdown-menu {display: block;}}
Chris Aelbrecht
1
Também para tornar o link com filhos clicável, você deve remover o "data-toggle = 'dropdown'" na tag <a>.
Joan16v
2
Aqui está um código que funciona com o mais novo Bootstrap 3 Versão: jsfiddle.net/sgruenwald/2tt8f8xg
Stefan Gruenwald
910

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 litag 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-toggleelemento 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 :afterpseudo 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

Minha cabeça dói
fonte
79
Também foi necessário adicionar margin: 0;, caso contrário, a margem de 1 px acima .dropdown-menucausa comportamento de buggy.
Salman von Abbas
12
Solução simples, mas o link pai ainda não pode ser clicado. Estou usando o último bootstrap com tema de raízes.
perfil completo de Krunal
5
Nota: Sim, funciona - isso funcionará em qualquer navegador suportado pelo Twitter. @ GeorgeEdison Esse é o CSS básico - que parte não seria suportada pelo IE8? Se você estiver tendo problemas, poste uma pergunta, sem comentários enganosos.
Minha cabeça dói
3
@MyHeadHurts: Depois de mais pesquisas, verificou-se que este era realmente um bug do Bootstrap e que foi corrigido apenas cinco dias atrás.
Nathan Osman
5
@ Krunal para poder clicar no link, você deve remover o data-toggle="dropdown"atributo.
precisa saber é o seguinte
230

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:

  1. Clicar no link suspenso abrirá o menu suspenso. E ele permanecerá aberto, a menos que o usuário clique em outro lugar ou passe o mouse sobre ele, criando uma interface do usuário estranha.
  2. Há uma margem de 1 px entre o link suspenso e o menu suspenso. Isso faz com que o menu suspenso fique oculto se você se mover lentamente entre o menu suspenso e o menu suspenso.

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;
}
Preço de Cory
fonte
15
Para corrigir o clique deliberado, acabei de remover o data-toggle="dropdown"atributo, que parecia funcionar.
Anthony Briggs
5
Solução (2) para botões nav-pill:.nav-pills .dropdown-menu { margin-top: 0px; }
Loren
1
Para corrigir o problema já referido anteriormente li.dropdown: hover> ul.dropdown menu
Archimedes Trajano
12
remoção de "classe" e "data-toggle" atributos a partir de links nav fazê-lo parar funcionando bem em celulares e tablets :(
Mosijava
1
Se você removeu o atributo data-toggle = "dropdown", não poderá expandir o menu suspenso usando o teclado. Portanto, não será compatível com 508. Como você pode desativar o clique, mas manter a funcionalidade do teclado?
duyn9uyen
130

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();
});
John Montgomery
fonte
13
Como isso. De qualquer maneira, estou usando o JQuery com o material do Bootstrap e ainda permite a funcionalidade padrão de 'clique' em dispositivos com tela de toque.
Duck no creme
Usou isso. Gosto que ele também permita a funcionalidade de clique, para celulares, mas para desktops o foco é perfeito.
Stuart
1
Eu usei isso, mas também o estendi para ser usado em menus suspensos que não estão em uma navegação. Eu adiciono classe dropdown-hover à div btn-group e usei esse localizador jQuery $ ('ul.nav li.dropdown, .dropdown-hover'). Hover (function () {. Thanks!
Brandon
Usou este, bonito e pequeno. A versão css não permitiu submenu para estadia exibido e 200ms foi muito rápido, então eu mudei para $('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
Damien
isso não parece trabalhar com jqLite que acompanha anguraljs
nuander
70

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.

estereociência
fonte
2
Ótima solução! Também removi o atributo data-toggle = "dropdown" do link para tornar o link principal clicável.
Sergey
Essa é uma boa dica, Sergey. Sempre me certifico de que o link superior não vá a lugar nenhum, para que também funcione em tablets e telefones.
stereoscience
1
@ Emery, eu não recomendaria fazer isso. Você quebraria a funcionalidade para usuários móveis. Eles não podem usar a função de foco instantâneo para abrir um menu e precisam poder clicar nele.
Paul
2
Isso é incrivelmente curto e fácil, enquanto ainda é compatível com telas sensíveis ao toque. Deve ser votado muito mais.
Max
Isso parece muito bom. Alguma idéia de como adicionar um pouco de animação usando transições CSS?
Fred Rocha
69

Simplesmente personalize seu estilo CSS em três linhas de código

.dropdown:hover .dropdown-menu {
   display: block;
}
Ranjith
fonte
22

Se você possui um elemento com uma dropdownclasse 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>

Aqui está uma demonstração

Esta resposta foi baseada na resposta do @Michael , fiz algumas alterações e adicionei algumas adições para que o menu suspenso funcione corretamente

Amr
fonte
Perfeito. Muito obrigado.
Antikbd
20

[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 delayparâ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 #concrete5IRC) 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.

Veja a postagem do blog para mais informações.

CWSpear
fonte
17

Isso funcionou para mim:

.dropdown:hover .dropdown-menu {
    display: block;
}
Amay Kulkarni
fonte
1
Com o celular, no entanto - é estranho.
Radmation
A margem entre o menu e o menu suspenso torna isso inútil.
Antikbd
15

Isso está embutido no Bootstrap 3. Basta adicionar isso ao seu CSS:

.dropdown:hover .dropdown-menu {
    display: block;
}
BSUK
fonte
10

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');
});
caarlos0
fonte
3
Alterei seu código para, 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.
Farjam
Este código não funcionará mais com as versões mais recentes.
Paul
9

Você pode usar o $().dropdown('toggle')método padrão para alternar o menu suspenso ao passar o mouse:

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

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.

Maxim Filippov
fonte
Meu .dropdown-menu tinha, o margin: 2px 0 0;que significava que um lento mouseEnter de cima escondeu o menu prematuramente. ul.dropdown-menu{ margin-top: 0; }
precisa
8

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>
Alex
fonte
5
Este é o trabalho de Cameron Lança, pensei que iria dar-lhe o shoutout: cameronspear.com/blog/bootstrap-dropdown-on-hover-plugin
kelpie
8

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'); 
});
Mark Williams
fonte
Resultado indesejado: mouse, clique e mouseout deixará o menu aberto. Este não é o que eu quero ...
Wietse
Usando isso, executar a função de inicialização para abrir o menu suspenso, Essa função faz muitas outras coisas, como expandiu-ária = "true"
Farhad Sakhaei
7

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...

Mehdi Maghrooni
fonte
5

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;
}
Sudharshan
fonte
2
esta é a resposta correta, o bootstrap está pronto para passar o mouse no menu suspenso, se o mouse não sair do menu suspenso. A remoção da margem superior permite ir do link para o menu sem interrupção e, portanto, sem o fechamento automático do menu. E esta solução permite manter o comportamento correto para dispositivos de toque
Nicolas Janel
5

Provavelmente, essa é uma ideia estúpida, mas para remover a seta apontando para baixo, você pode excluir o

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

Isso não faz nada para o apontador, embora ...

stinaq
fonte
5

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


Por que eu fiz isso quando já existem muitas soluções?

Eu tive problemas com todas as soluções existentes anteriormente. Os CSS simples não estão usando a .openclasse 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.

István Ujj-Mészáros
fonte
Qual a sua opinião sobre github.com/vadikom/smartmenus ? Não consigo decidir, as duas bibliotecas parecem realmente boas.
Csaba Toth
2
Os menus inteligentes parecem realmente bons; pode ser melhor para menus. Meu plug-in é apenas uma pequena adição aos menus suspensos de inicialização, não faz mais do que abrir um menu suspenso ao passar o mouse, enquanto o smartmenu também suporta submenus e faz outras coisas sofisticadas.
István Ujj-Mészáros
1
Obrigado. Vejo que o código do smartmenu é muito extenso e também há muito CSS. Até agora eu fui com 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.
Csaba Toth
4

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.

Jibato
fonte
Gostaria de usar seu código, mas estou tendo problemas para fazê-lo funcionar corretamente. Primeiro, como remover o hover () para dispositivos móveis e usá-lo apenas para computadores? Quando uso seu código e redimensiono a janela para celular, recebo as funcionalidades hover () e click (). Mas ainda mais estranho ... é que esse comportamento irá parar Quando eu atualizo o navegador, ha! Você poderia me mostrar como consertar isso? Eu preciso que os submenus da área de trabalho sejam exibidos ao passar o mouse () e clique em () para mostrar submenus no celular Sem precisar atualizar o navegador, mesmo ao redimensionar a janela para funcionar corretamente. Espero que isso esteja claro #
2222 Dec28
ok, isso faz sentido e tentarei executar sua solução da maneira que você recomenda. Obrigado!
precisa saber é o seguinte
Use este melhor método: @falter
Farhad Sakhaei
4
$('.dropdown').hover(function(e){$(this).addClass('open')})
Савостьянов Максим
fonte
1
Forneça alguns detalhes para sua resposta.
Arnold Daniels
3

Isso ocultará os que estão

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

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;
    }
}
Kevin Nuut
fonte
Por que você quer esconder isso? Agora, os usuários móveis não têm como acessar os links que estão no submenu. É melhor desativar o efeito de foco em um dispositivo móvel e manter o menu suspenso intacto. Dessa forma, eles podem abri-lo clicando nele.
Paul
3

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;
    }
}
Fizex
fonte
3

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;
    }
}
Kash
fonte
Isso não funciona muito bem para alguns temas em que há uma lacuna entre o item de menu e o menu suspenso. O menu desaparecerá quando o mouse se mover para esse espaço.
Ndbroadbent
2

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') })
});

}); 
Hari Krishnan
fonte
2

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);
});
Sarah Vessels
fonte
2

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 .

johna
fonte
2

Isso funciona para o WordPress Bootstrap:

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

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.

Crisan Raluca Teodora
fonte