Menu suspenso de inicialização com pairar

179

OK, então o que eu preciso é bem direto.

Eu configurei uma barra de navegação com alguns menus suspensos (usando class="dropdown-toggle" data-toggle="dropdown") e funciona bem.

O problema é que " onClick" funciona , enquanto eu preferiria que funcionasse " onHover".

Existe alguma maneira embutida de fazer isso?

Dr.Kameleon
fonte
Veja meu plugin adequada recém-publicado que impede que os problemas do abaixo CSS e JS soluções: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Mészáros ujj-

Respostas:

338

A solução mais fácil seria em CSS. Adicione algo como ...

.dropdown:hover .dropdown-menu {
    display: block;
    margin-top: 0; // remove the gap so it doesn't close
 }

Violino de trabalho

brbcoding
fonte
3
Muito melhor do que soluções longas e "totalmente construídas". Basta adicionar isso e o menu suspenso 'clique' padrão funciona em foco, sem alterações extras.
IamFace 13/04
47
Este conflito vontade com construído no menu do celular dobrável, então você deve envolvê-la em um @media ponto de ruptura (min-width: 480px)
Billy Shih
7
Também digno de nota: se você tem um menu suspenso com relacionamentos pai-filho, por exemplo, em um tema wordpress, precisa remover o data-toggleatributo para tornar o item pai clicável ... Apenas observe os danos colaterais nas telas de dispositivos móveis.
Ken príncipe
2
Existe alguma maneira fácil de desativar a exibição ao clicar e manter apenas o comportamento de passar o mouse?
Micer
1
@Micer, acabei de publicar um plugin no qual você pode desativar o evento click. O plug-in funciona sem qualquer corte CSS, usando apenas API do Bootstrap javascript, por isso é compatível com todos os dispositivos: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Mészáros ujj-
66

A melhor maneira de fazer isso é acionar apenas o evento de clique de inicialização com um cursor do mouse. Dessa forma, ele ainda deve permanecer amigável ao dispositivo sensível ao toque

$('.dropdown').hover(function(){ 
  $('.dropdown-toggle', this).trigger('click'); 
});
Mark Williams
fonte
1
falha se você tem mais de um nível suspenso
Connie DeCinko
1
Não está trabalhando com o link principal
pio 30/03
existe uma maneira de remover a classe Active quando o menu suspenso é fechado?
Brainvision 17/05
Há uma lacuna de pixels entre o elemento suspenso e o menu que pode fazer com que o menu para esconder em algum momento de cruzar, a menos que você é rápido
Matt
1
O uso de várias listas suspensas precisa de uma filtragem 'mais próxima'.
err
57

Você pode usar a função de foco instantâneo do jQuery.

Você só precisa adicionar a classe openquando o mouse entra e remover a classe quando o mouse sai da lista suspensa.

Aqui está o meu código:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});
adhi
fonte
10
Muito melhor do que a resposta aceita. Isso mantém intacta toda a lógica e estilo de inicialização. Embora eu aconselhe o uso da segunda chamada de volta e use explicitamente removeClass e addClass para evitar algum comportamento estranho quando você clica no botão (onde ele abriria quando você deixasse o botão e fecharia quando o inserir).
Bastiaan Linders 15/05
3
Eu também acho que esta é a melhor resposta. Para obtê-lo para trabalhar com Bootstrap menu de 4, eu tive que usar showem vez de open, e também incluem a dropdown-menu: $('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(. Desculpe pela formatação)
Robin Zimmermann
Não funcione se você tiver dois itens de menu suspensos. Ao passar o mouse sobre qualquer item, o menu mostrará os dois submenus
Juan Antonio Tubío 16/10
23

Uma maneira fácil, usando jQuery, é esta:

$(document).ready(function(){
    $('ul.nav li.dropdown').hover(function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(200);
    }, function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(200);
    });  
});
Biagio Chirico
fonte
Adoro a transição suave, no entanto, faz com que todos os níveis do menu se expandam, em vez de apenas o primeiro nível. Não quero que os menus de segundo nível apareçam até que passe o mouse sobre o pai deles.
Connie DeCinko
1
Para obter o primeiro nível somente, adicione .first() - $(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);...
JEdot
9

Para CSS, fica louco quando você também clica nele. Este é o código que estou usando, mas também não altera nada na visualização para dispositivos móveis.

$('.dropdown').mouseenter(function(){
    if(!$('.navbar-toggle').is(':visible')) { // disable for mobile view
        if(!$(this).hasClass('open')) { // Keeps it open when hover it again
            $('.dropdown-toggle', this).trigger('click');
        }
    }
});
user1079877
fonte
Uma beleza! Tx! As alternativas CSS não funcionarão no Bootstrap 3 e além.
Pedro Ferreira
5

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 no evento de clique e você deseja que ele funcione no 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 100ms. 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
Este código tem muitos problemas no bootstrap v3. 1.) Se houver mais de uma lista suspensa, todas as listas suspensas serão exibidas quando uma delas passar o mouse. 2.) Em telas pequenas, pairar mostra o menu suspenso de uma maneira estranha.
KayakinKoder
4

Isto é o que eu uso para fazê-lo suspenso ao passar o mouse com algum jQuery

$(document).ready(function () {
    $('.navbar-default .navbar-nav > li.dropdown').hover(function () {
        $('ul.dropdown-menu', this).stop(true, true).slideDown('fast');
        $(this).addClass('open');
    }, function () {
        $('ul.dropdown-menu', this).stop(true, true).slideUp('fast');
        $(this).removeClass('open');
    });
});
Amir5000
fonte
Bom, mas não suporta submenus.
Connie DeCinko
3

Experimente fazer isso usando a função hover com animações fadein fadeout

$('ul.nav li.dropdown').hover(function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);
}, function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);
});
Rakesh Vadnal
fonte
Esta animação não está funcionando na 3ª profundidade, mas está funcionando na 2ª profundidade. Você tem alguma outra solução para a 3ª profundidade?
Jilani Um
por favor, adicione JSFiddle para referência
Rakesh Vadnal
2

Isso o ajudará a criar sua própria classe de foco para o bootstrap:

CSS:

/* Hover dropdown */
.hover_drop_down.input-group-btn ul.dropdown-menu{margin-top: 0px;}/*To avoid unwanted close*/
.hover_drop_down.btn-group ul.dropdown-menu{margin-top:2px;}/*To avoid unwanted close*/
.hover_drop_down:hover ul.dropdown-menu{
   display: block;
}

As margens são definidas para evitar fechamentos indesejados e são opcionais.

HTML:

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

Não se esqueça de remover o atributo do botão data-toggle = "dropdown" se você deseja remover o onclick aberto, e isso também funcionará quando a entrada for anexada ao dropdown.

Sabri Aziri
fonte
2

Isso só passa a barra de navegação quando você não está em um dispositivo móvel, porque acho que passar a navegação não funciona bem em dispositivos móveis:

    $( document ).ready(function() {

    $( 'ul.nav li.dropdown' ).hover(function() {
        // you could also use this condition: $( window ).width() >= 768
        if ($('.navbar-toggle').css('display') === 'none' 
            && false === ('ontouchstart' in document)) {

            $( '.dropdown-toggle', this ).trigger( 'click' );
        }
    }, function() {
        if ($('.navbar-toggle').css('display') === 'none'
            && false === ('ontouchstart' in document)) {

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

});
solarbaypilot
fonte
Você pode encontrar uma solução muito melhor aqui: github.com/CWSpear/bootstrap-hover-dropdown .
solarbaypilot
2

Eu tento outras soluções, estou usando o bootstrap 3, mas o menu suspenso fecha muito rapidamente para passar por cima dele

supunha que você adicionasse class = "dropdown" a li, adicionei um tempo limite

var hoverTimeout;
$('.dropdown').hover(function() {
    clearTimeout(hoverTimeout);
    $(this).addClass('open');
}, function() {
    var $self = $(this);
    hoverTimeout = setTimeout(function() {
        $self.removeClass('open');
    }, 150);
});
al404IT
fonte
2

Atualizado com um plugin adequado

Publiquei um plug-in adequado para a funcionalidade suspensa suspensa, na qual você pode definir o que acontece ao clicar no dropdown-toggleelemento:

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 no elemento de alternância do menu suspenso quando o menu suspenso estiver visível.

Os js estão interferindo no clique .dropdown-toggle, então o menu suspenso aparece ao passar o mouse, depois o oculta ao clicar em um menu suspenso aberto, e sair do mouse aciona o menu suspenso para aparecer novamente. Algumas das soluções js estão travando 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.

István Ujj-Mészáros
fonte
1
    $('.navbar .dropdown').hover(function() {
      $(this).find('.dropdown-menu').first().stop(true, true).slideDown(150);
    }, function() {
      $(this).find('.dropdown-menu').first().stop(true, true).slideUp(105)
    });
Waqar Ahmed
fonte
1

Acionar um clickevento com um hovererro pequeno. Se mouse-ine, em seguida, a clickcria um efeito vice-versa. É opensquando mouse-oute closequando mouse-in. Uma solução melhor:

$('.dropdown').hover(function() {
    if (!($(this).hasClass('open'))) {
        $('.dropdown-toggle', this).trigger('click');
    }
}, function() {
    if ($(this).hasClass('open')) {
        $('.dropdown-toggle', this).trigger('click');
    }
});
umesh kadam
fonte
1

html

        <div class="dropdown">

            <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
                Dropdown Example <span class="caret"></span>
            </button>

            <ul class="dropdown-menu">
                <li><a href="#">HTML</a></li>
                <li><a href="#">CSS</a></li>
                <li><a href="#">JavaScript</a></li>
            </ul>

        </div> 

jquery

        $(document).ready( function() {                

            /* $(selector).hover( inFunction, outFunction ) */
            $('.dropdown').hover( 
                function() {                        
                    $(this).find('ul').css({
                        "display": "block",
                        "margin-top": 0
                    });                        
                }, 
                function() {                        
                    $(this).find('ul').css({
                        "display": "none",
                        "margin-top": 0
                    });                        
                } 
            );

        });

codepen

antelove
fonte
0

A solução que estou propondo detecta se o dispositivo não é sensível ao toque e se o navbar-toggle(menu hambúrguer) não está visível e faz com que o item de menu pai revele o submenu ao passar o mouse e siga o link no clique .

Também faz com que o margem seja 0, porque a diferença entre a barra de navegação e o menu em algum navegador não permitirá que você passe o mouse pelos subitens

$(function(){
    function is_touch_device() {
        return 'ontouchstart' in window        // works on most browsers 
        || navigator.maxTouchPoints;       // works on IE10/11 and Surface
    };

    if(!is_touch_device() && $('.navbar-toggle:hidden')){
      $('.dropdown-menu', this).css('margin-top',0);
      $('.dropdown').hover(function(){ 
          $('.dropdown-toggle', this).trigger('click').toggleClass("disabled"); 
      });			
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<ul id="nav" class="nav nav-pills clearfix right" role="tablist">
    <li><a href="#">menuA</a></li>
    <li><a href="#">menuB</a></li>
    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">menuC</a>
        <ul id="products-menu" class="dropdown-menu clearfix" role="menu">
            <li><a href="">A</a></li>
            <li><a href="">B</a></li>
            <li><a href="">C</a></li>
            <li><a href="">D</a></li>
        </ul>
    </li>
    <li><a href="#">menuD</a></li>
    <li><a href="#">menuE</a></li>
</ul>

$(function(){
  $("#nav .dropdown").hover(
    function() {
      $('#products-menu.dropdown-menu', this).stop( true, true ).fadeIn("fast");
      $(this).toggleClass('open');
    },
    function() {
      $('#products-menu.dropdown-menu', this).stop( true, true ).fadeOut("fast");
      $(this).toggleClass('open');
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<ul id="nav" class="nav nav-pills clearfix right" role="tablist">
    <li><a href="#">menuA</a></li>
    <li><a href="#">menuB</a></li>
    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">menuC</a>
        <ul id="products-menu" class="dropdown-menu clearfix" role="menu">
            <li><a href="">A</a></li>
            <li><a href="">B</a></li>
            <li><a href="">C</a></li>
            <li><a href="">D</a></li>
        </ul>
    </li>
    <li><a href="#">menuD</a></li>
    <li><a href="#">menuE</a></li>
</ul>

GiorgosK
fonte
0

Menu suspenso Bootstrap Trabalhe em foco e permaneça próximo ao clicar adicionando a propriedade display: block; em css e removendo esses atributos data-toggle = "dropdown" role = "button" da tag button

.dropdown:hover .dropdown-menu {
  display: block;
}
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">                                     
  <div class="dropdown">
    <button class="btn btn-primary dropdown-toggle">Dropdown Example
    <span class="caret"></span></button>
    <ul class="dropdown-menu">
      <li><a href="#">HTML</a></li>
      <li><a href="#">CSS</a></li>
      <li><a href="#">JavaScript</a></li>
    </ul>
  </div>
</div>

</body>
</html>

Super Model
fonte