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.


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


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


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

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

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.


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

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


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.


17

Isso funcionou para mim:

.dropdown:hover .dropdown-menu {
    display: block;
}

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

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

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

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.


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>

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

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


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

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


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.


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.


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


3

Isso ocultará os que estão

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

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

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

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

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

}); 

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

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 .


2

Isso funciona para o WordPress Bootstrap:

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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.