Bootstrap Dropdown con Hover

179

Bien, entonces lo que necesito es bastante sencillo.

He configurado una barra de navegación con algunos menús desplegables (usando class="dropdown-toggle" data-toggle="dropdown"), y funciona bien.

La cosa es que funciona " onClick", mientras que preferiría que funcionara " onHover".

¿Hay alguna forma integrada de hacer esto?

Dr. Kameleon
fuente
Vea mi complemento apropiado recientemente publicado que evita los problemas de las soluciones CSS y js a continuación: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Respuestas:

338

La solución más fácil sería en CSS. Agrega algo como ...

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

Violín de trabajo

Brbcoding
fuente
3
Mucho mejor que las soluciones largas "completas". Simplemente agregue esto y el menú desplegable predeterminado 'clic' funciona al pasar el mouse sin cambios adicionales.
IamFace
47
Esto entrará en conflicto con el menú móvil plegable incorporado, por lo que debe envolverlo en un punto de interrupción @media (ancho mínimo: 480px)
Billy Shih
77
También cabe destacar: si tiene un menú desplegable con relaciones padre-hijo, por ejemplo, en un tema de WordPress, debe eliminar el data-toggleatributo para que el elemento padre pueda hacer clic ... Solo tenga cuidado con el daño colateral en las pantallas de los dispositivos móviles.
Ken Prince
2
¿Hay alguna manera fácil de deshabilitar la visualización al hacer clic y mantener solo el comportamiento de desplazamiento?
Micer
1
@Micer, acabo de publicar un complemento en el que puedes deshabilitar el evento click. El complemento funciona sin ningún hack CSS, usando solo la API de JavaScript Bootstrap, por lo que es compatible con todos los dispositivos: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros
66

La mejor manera de hacerlo es activar un evento de clic de arranque con un desplazamiento. De esta manera, debe seguir siendo amigable con el dispositivo táctil

$('.dropdown').hover(function(){ 
  $('.dropdown-toggle', this).trigger('click'); 
});
Mark Williams
fuente
1
falla si tienes más de un nivel desplegable
Connie DeCinko
1
No funciona con el enlace principal
pio
¿hay alguna forma de eliminar la clase Active una vez que se cierra el menú desplegable?
brainvision
Hay una brecha de píxeles entre el elemento desplegable y el menú que puede hacer que el menú se oculte en algún momento cruzando, a menos que sea rápido
Matt
1
El uso de múltiples menús desplegables necesita un filtrado 'más cercano'.
err
57

Puede usar la función de desplazamiento de jQuery.

Solo necesita agregar la clase opencuando el mouse ingresa y eliminar la clase cuando el mouse sale del menú desplegable.

Aquí está mi código:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});
adhi
fuente
10
Mucho mejor que la respuesta aceptada en mi humilde opinión. Esto mantiene intacta toda la lógica de arranque y el estilo. Aunque aconsejaría usar la segunda devolución de llamada y usar explícitamente removeClass y addClass para evitar un comportamiento extraño cuando haya hecho clic en el botón (donde se abriría cuando deja el botón y se cierra cuando lo ingresa).
Bastiaan Linders
3
También creo que esta es la mejor respuesta. Para que funcione con el menú Bootstrap 4, tuve que usar en showlugar de open, y también incluir dropdown-menu: $('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(Perdón por el formato.)
Robin Zimmermann
No funcione si tiene dos elementos del menú desplegable. Al pasar el cursor sobre cualquier elemento desplegable, se mostrarán ambos submenús
Juan Antonio Tubío
23

Una manera fácil, usando jQuery, es 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
fuente
Me encanta la transición suave, sin embargo, hace que todos los niveles del menú se expandan en lugar de solo el primer nivel. No quiero que aparezcan menús de segundo nivel hasta que pase el mouse sobre sus padres.
Connie DeCinko
1
Para obtener solo el primer nivel, agregue .first() - $(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);...
JEdot
9

Para CSS se vuelve loco cuando también haces clic en él. Este es el código que estoy usando, tampoco cambia nada para la vista móvil.

$('.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');
        }
    }
});
usuario1079877
fuente
¡Una belleza! Tx! Las alternativas CSS no funcionarán en Bootstrap 3 y más allá.
Pedro Ferreira
5

Entonces tienes 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 funciona en eventos de clic, y desea que funcione en eventos de desplazamiento. Esto es muy simple, solo use 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();
        })
    })
})

Esto funciona muy bien y aquí está la explicación: tenemos un botón y un menú. Cuando pasamos el botón, mostramos el menú, y cuando pasamos el mouse del botón, ocultamos el menú después de 100 ms. Si te preguntas por qué lo uso, es porque necesitas tiempo para arrastrar el cursor desde el botón sobre el menú. Cuando está en el menú, la hora se restablece y puede permanecer allí tantas veces como desee. Cuando salga del menú, ocultaremos el menú instantáneamente sin ningún tiempo de espera.

He usado este código en muchos proyectos, si encuentra algún problema al usarlo, no dude en hacerme preguntas.

Crisan Raluca Teodora
fuente
Este código tiene muchos problemas en bootstrap v3. 1.) Si hay más de un menú desplegable, se muestran todos los menús desplegables cuando se pasa por encima. 2.) En pantallas pequeñas, el desplazamiento muestra el menú desplegable de una manera extraña.
KayakinKoder
4

Esto es lo que uso para que sea desplegable al pasar el mouse con un poco de 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
fuente
Agradable pero no admite submenús.
Connie DeCinko
3

Intente esto usando la función de desplazamiento con animaciones 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
fuente
Esta animación no funciona en tercera profundidad, pero sí en segunda profundidad. ¿Tienes alguna otra solución para la 3ra profundidad?
Jilani A
agregue JSFiddle como referencia
Rakesh Vadnal
2

Esto te ayudará a crear tu propia clase de vuelo estacionario para 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;
}

Los márgenes están configurados para evitar el cierre no deseado y son opcionales.

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>

No olvide eliminar el atributo de botón data-toggle = "dropdown" si desea eliminar onclick open, y esto también funcionará cuando la entrada se agregue con desplegable.

Sabri Aziri
fuente
2

Esto solo pasa la barra de navegación cuando no estás en un dispositivo móvil, porque encuentro que pasar la navegación no funciona bien en los dispositivos móviles:

    $( 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
fuente
Puede encontrar una solución mucho mejor aquí: github.com/CWSpear/bootstrap-hover-dropdown .
solarbaypilot
2

Intento con otras soluciones, estoy usando Bootstrap 3, pero el menú desplegable se cierra demasiado rápido para pasarlo

supuse que agregas class = "dropdown" a li, agregué un tiempo de espera

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

Actualizado con un complemento adecuado

He publicado un complemento adecuado para la funcionalidad del menú desplegable, en el que incluso puedes definir qué sucede al hacer clic en el dropdown-toggleelemento:

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


¿Por qué lo hice, cuando ya hay muchas soluciones?

Tuve problemas con todas las soluciones existentes anteriormente. Los CSS simples no están utilizando la .openclase en el .dropdown, por lo que no habrá comentarios sobre el elemento de alternancia desplegable cuando el menú desplegable esté visible.

Los js están interfiriendo con hacer clic en .dropdown-toggle, por lo que el menú desplegable aparece al pasar el mouse, luego lo oculta al hacer clic en un menú desplegable abierto, y al mover el mouse, el menú desplegable se activará nuevamente. Algunas de las soluciones js están frenando la compatibilidad con iOS, algunos complementos no funcionan en los navegadores de escritorio modernos que admiten los eventos táctiles.

Es por eso que hice el complemento Bootstrap Dropdown Hover que evita todos estos problemas al usar solo la API estándar de Bootstrap javascript, sin ningún tipo de pirateo.

István Ujj-Mészáros
fuente
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
fuente
1

La activación de un clickevento con a hovertiene un pequeño error. Si mouse-iny luego a clickcrea un efecto viceversa. Es openscuando mouse-outy closecuando mouse-in. Una mejor solución:

$('.dropdown').hover(function() {
    if (!($(this).hasClass('open'))) {
        $('.dropdown-toggle', this).trigger('click');
    }
}, function() {
    if ($(this).hasClass('open')) {
        $('.dropdown-toggle', this).trigger('click');
    }
});
umesh kadam
fuente
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

antílope
fuente
0

La solución que propongo detecta si no es un dispositivo táctil y que el navbar-toggle(menú de hamburguesas) no es visible y hace que el elemento del menú principal revele el submenú al pasar el mouse y sigue su enlace al hacer clic .

También hace que el margen sea superior a 0 porque la brecha entre la barra de navegación y el menú en algunos navegadores no le permitirá desplazarse a los subelementos

$(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
fuente
0

Menú desplegable Bootstrap Trabaje al pasar el mouse y manténgase cerca al hacer clic agregando la pantalla de propiedades : bloque; en css y eliminando estos atributos data-toggle = "dropdown" role = "button" de la etiqueta del botón

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

Súper modelo
fuente