css - pasar - menu hamburguesa bootstrap



Cómo hacer que el menú desplegable de Twitter Bootstrap se desplace al pasar el mouse en lugar de hacer clic (20)

Aún mejor con 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');
});

Me gustaría que mi menú de Bootstrap se desplegara automáticamente al pasar el cursor, en lugar de tener que hacer clic en el título del menú. También me gustaría perder las pequeñas flechas al lado de los títulos del menú.


Answer #1

Además de la respuesta de "Me duele la cabeza" (que fue genial):

ul.nav li.dropdown:hover ul.dropdown-menu{
    display: block;    
}

Hay 2 problemas persistentes:

  1. Al hacer clic en el enlace desplegable se abrirá el menú desplegable. Y se mantendrá abierto a menos que el usuario haga clic en otro lugar, o vuelva sobre él, creando una IU incómoda.
  2. Hay un margen de 1px entre el enlace desplegable y el menú desplegable. Esto hace que el menú desplegable se oculte si se mueve lentamente entre el menú desplegable y el menú desplegable.

La solución a (1) es eliminar los elementos de "clase" y "conmutador de datos" del enlace de navegación

<a href="#">
     Dropdown
     <b class="caret"></b>
</a>

Esto también le brinda la posibilidad de crear un enlace a su página principal, lo cual no fue posible con la implementación predeterminada. Simplemente puede reemplazar el "#" con cualquier página que desee enviar al usuario.

La solución para (2) es eliminar el margen superior en el selector de menú desplegable.

.navbar .dropdown-menu {
 margin-top: 0px;
}

Answer #2

Creé un menú desplegable puro al pasar el mouse basado en el último marco de Bootstrap (v2.0.2) que tiene soporte para múltiples submenús y pensé que lo publicaría para futuros usuarios:

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


Answer #3

En mi opinión, la mejor manera es así:

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

Marcado de la muestra:

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

Answer #4

Esta es probablemente una idea estúpida, pero solo para eliminar la flecha que apunta hacia abajo, puede eliminar la

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

Esto no hace nada para el apuntando hacia arriba, aunque ...


Answer #5

Esto debería ocultar los menús desplegables y sus caracteres si son más pequeños que una tableta.

@media (max-width: 768px) {
    .navbar ul.dropdown-menu, .navbar li.dropdown b.caret {
        display: none;
    }
}

Answer #6

Esto funcionó para mí:

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

Answer #7

Esto funciona para WordPress Bootstrap:

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

Answer #8

Hay muchas soluciones realmente buenas aquí. Pero pensé que seguiría y pondría el mío aquí como otra alternativa. Es solo un simple fragmento de jQuery que lo hace de la forma en que lo haría bootstrap si admitiera el desplazamiento de elementos desplegables en lugar de solo hacer clic. Solo probé esto con la versión 3, así que no sé si funcionaría con la versión 2. Guárdelo como un fragmento de código en su editor y téngalo al toque de una tecla.

<script>
    $(function() {
        $(".dropdown").hover(
            function(){ $(this).addClass('open') },
            function(){ $(this).removeClass('open') }
        );
    });
</script>

Básicamente, solo dice que cuando se desplaza sobre la clase desplegable, se le agregará la clase abierta. Entonces simplemente funciona. Cuando dejas de moverte en el li padre con la clase desplegable o en el niño ul / li's, se elimina la clase abierta. Obviamente, esta es solo una de las muchas soluciones, y puede agregarla para que funcione solo en instancias específicas de .downdown. O agregue una transición al padre o hijo.


Answer #9

He publicado un complemento adecuado para la funcionalidad de desplazamiento hacia abajo de Bootstrap 3, en el que incluso puede definir lo que sucede al hacer clic en el elemento dropdown-toggle (el clic puede desactivarse):

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

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

Tuve problemas con todas las soluciones previamente existentes. Los CSS simples no utilizan la clase .open en el .dropdown , por lo que no habrá retroalimentación sobre el elemento de conmutación desplegable cuando el desplegable esté visible.

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

Es por eso que hice el complemento github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover que evita todos estos problemas usando solo la API de Bootstrap javascript estándar, sin ningún tipo de pirateo . Incluso los atributos de Aria están funcionando bien con este complemento.


Answer #10

La mejor manera de hacerlo es simplemente activar el evento de clic de Bootstrap con un hover. De esta manera, aún debe seguir siendo compatible con dispositivos táctiles.

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

Answer #11

La solución jQuery es buena, pero tendrá que lidiar con los eventos de clic (para dispositivos móviles o tabletas), ya que el desplazamiento no funcionará correctamente ... ¿Podría tal vez hacer un cambio de tamaño en la ventana?

La respuesta de Andres Ilich parece funcionar bien, pero debería estar envuelta en una consulta de medios:

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

Answer #12

Para lograr que el menú se coloque automáticamente al pasar el mouse, esto se puede lograr utilizando CSS básico. Debe calcular el selector en la opción de menú oculto y luego configurarlo para que se muestre como bloque cuando la etiqueta li adecuada se desplace por encima. Tomando el ejemplo de la página de inicio de Twitter, el selector sería el siguiente:

ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;    
}

Sin embargo, si está utilizando las funciones de respuesta de Bootstrap, no querrá esta funcionalidad en una barra de navegación colapsada (en pantallas más pequeñas). Para evitar esto, envuelva el código anterior en una consulta de medios:

@media (min-width: 979px) {
  ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;
  }
}

Para ocultar la flecha (intercalación), esto se hace de diferentes maneras dependiendo de si está utilizando la versión 2 o inferior de Twitter Bootstrap o la versión 3:

Bootstrap 3

Para eliminar el símbolo de intercalación en la versión 3, solo necesita eliminar el elemento de anclaje .dropdown-toggle : <b class="caret"></b> :

<a class="dropdown-toggle" data-toggle="dropdown" href="#">
    Dropdown
    <b class="caret"></b>    <-- remove this line
</a>

Bootstrap 2 y más bajo

Para eliminar la versión de la versión 2, necesita un poco más de información sobre CSS y sugiero ver cómo funciona el pseudo elemento :after con más detalle. Para comenzar su comprensión, para apuntar y eliminar las flechas en el ejemplo de inicio de sesión de Twitter, usaría el siguiente selector y código de CSS:

a.menu:after, .dropdown-toggle:after {
    content: none;
}

Funcionará a su favor si analiza más a fondo cómo funcionan y no solo utiliza las respuestas que le he dado.

Gracias a @CocaAkat por señalar que nos faltaba el combinador de niños ">" para evitar que se muestren los submenús en el elemento principal.


Answer #13

Para mejorar la respuesta de Sudharshan, envuelvo esto en una consulta de medios para evitar que se desplace el mouse cuando en los anchos de pantalla XS ...

@media (min-width:768px)
{
    ul.nav li.dropdown:hover > ul.dropdown-menu {
        display: block;    
    }

    .nav .dropdown-menu {
        margin-top: 0;
    }
}

Además, no se requiere el carácter en el marcado, solo la clase desplegable para el li .


Answer #14

Si tiene un elemento con una clase dropdown como esta (por ejemplo):

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

Luego, puede tener el menú desplegable para desplegarse automáticamente al pasar el mouse sobre, en lugar de tener que hacer clic en su título, usando este fragmento de código de 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>

Aquí hay una demo.

Esta respuesta se basó en la respuesta de @Michael . He realizado algunos cambios y agregado algunas adiciones para que el menú desplegable funcione correctamente.


Answer #15

Simplemente personaliza tu estilo CSS en tres líneas de código

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

Answer #16

Solo quiero agregar, que si tiene varios menús desplegables (como yo) debería escribir:

ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;    
}

Y funcionará correctamente.


Answer #17

También se agregó margin-top: 0 para restablecer el margen css del bootstrap para el menú desplegable, de modo que la lista del menú no desaparezca cuando el usuario pase lentamente del menú desplegable al menú.

ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;    
}

.nav .dropdown-menu {
    margin-top: 0;
}

Answer #18

[Actualización] El complemento está en GitHub y estoy trabajando en algunas mejoras (como usar solo con atributos de datos (no es necesario JS). He dejado el código a continuación, pero no es lo mismo que en GitHub.

Me gustó la versión puramente CSS, pero es bueno tener un retraso antes de que se cierre, ya que generalmente es una mejor experiencia para el usuario (es decir, no está castigado por un deslizamiento del mouse que sale 1 px fuera del menú desplegable, etc.), y como se menciona en los comentarios , existe ese 1px de margen con el que tiene que lidiar o, a veces, la navegación se cierra inesperadamente cuando se mueve al menú desplegable desde el botón original, etc.

Creé un pequeño complemento rápido que he usado en un par de sitios y ha funcionado muy bien. Cada elemento de navegación se maneja de forma independiente, por lo que tienen sus propios temporizadores de retardo, 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);
        });
    });
};  

El parámetro de delay es bastante autoexplicativo, y al instantlyCloseOthers , CloseOthers cerrará instantáneamente todos los demás menús desplegables que están abiertos cuando se pasa sobre uno nuevo.

No es CSS puro, pero espero que ayude a alguien más en esta hora tardía (es decir, este es un tema antiguo).

Si lo desea, puede ver los diferentes procesos por los que pasé (en una discusión sobre el #concrete5 IRC) para que funcione a través de los diferentes pasos que se detallan en esta página: https://gist.github.com/3876924

El enfoque de patrón de plugin es mucho más limpio para admitir temporizadores individuales, etc.

Vea la publicación del blog para más.


Answer #19

Para el caret ... No he visto ninguno que especifique CSS simple que bloquee totalmente el caret.

Aqui tienes:

.caret {
    display: none !important;
}




twitter-bootstrap