Cómo hacer que el menú desplegable de Twitter Bootstrap esté al pasar el mouse en lugar de hacer clic

Me gustaría que mi menú Bootstrap se desplegara automáticamente al pasar el mouse, 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

Creé un menú desplegable puro basado en el último marco de Bootstrap (v2.0.2) que tiene soporte para múltiples submenús y pensé en publicarlo 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>

Manifestación

Para que el menú caiga automáticamente al pasar el mouse, esto se puede lograr usando CSS básico. Debe configurar el selector para la opción de menú oculto y luego configurarlo para que se muestre como bloque cuando se coloca el licursor sobre la etiqueta correspondiente . Tomando el ejemplo de la página de arranque 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 (símbolo de intercalación), esto se hace de diferentes maneras dependiendo de si está utilizando Twitter Bootstrap versión 2 y anterior o versión 3:

Bootstrap 3

Para eliminar el signo de intercalación en la versión 3, solo necesita eliminar el HTML <b class="caret"></b>del .dropdown-toggleelemento de anclaje:

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

Bootstrap 2 y versiones inferiores

Para eliminar el signo de intercalación en la versión 2, necesita un poco más de información sobre CSS y le sugiero que observe cómo funciona el :afterpseudo elemento con más detalle. Para comenzar en su camino hacia la comprensión, para apuntar y eliminar las flechas en el ejemplo de arranque de Twitter, usaría el siguiente selector y código 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 usa las respuestas que le he dado.

Gracias a @CocaAkat por señalar que nos faltaba el combinador secundario ">" para evitar que se mostraran submenús en el elemento flotante principal.

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 permanecerá abierto a menos que el usuario haga clic en otro lugar, o pase el mouse sobre él, creando una interfaz de usuario incómoda.
  2. Hay un margen de 1 px 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 "class" y "data-toggle" 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 que no era posible con la implementación predeterminada. Simplemente puede reemplazar el "#" con cualquier página que desee enviar al usuario.

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

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

He usado un poco 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();
});

Simplemente personalice su estilo CSS en tres líneas de código

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

Aquí hay muchas soluciones realmente buenas. Pero pensé que seguiría adelante y pondría el mío aquí como otra alternativa. Es solo un simple fragmento de jQuery que lo hace de la misma manera que lo haría el bootstrap si fuera compatible con los menús desplegables en lugar de simplemente 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 en su editor y téngalo con solo presionar 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 deja de pasar el mouse sobre el li principal con la clase desplegable o el ul / li secundario, 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 .dropdown. O agregue una transición a padre o hijo.

Si tiene un elemento con una dropdownclase 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 hacer que el menú desplegable se despliegue automáticamente al pasar el cursor sobre, en lugar de tener que hacer clic en su título, utilizando este fragmento 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>

Aquí hay una demostración

Esta respuesta se basó en la respuesta de @Michael , hice algunos cambios y agregué algunas adiciones para que el menú desplegable funcione correctamente

[Actualización] El complemento está en GitHub y estoy trabajando en algunas mejoras (como usar solo con atributos de datos (no es necesario JS). Dejé 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 se castiga por un desliz del mouse que sale 1 px del menú desplegable, etc.), y como se menciona en los comentarios , hay 1px de margen con el que tiene que lidiar o, a veces, el navegador 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 funcionó 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 delayparámetro es bastante autoexplicativo y instantlyCloseOtherscerrará instantáneamente todos los demás menús desplegables que estén abiertos cuando pase el cursor sobre uno nuevo.

No es CSS puro, pero con suerte ayudará a alguien más a esta hora tardía (es decir, este es un hilo antiguo).

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

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

Consulte la publicación del blog para obtener más información.

Esto funcionó para mí:

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

Esto está integrado en Bootstrap 3. Simplemente agregue esto a su CSS:

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

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

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

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

Y funcionará correctamente.

Puede usar el $().dropdown('toggle')método predeterminado para alternar el menú desplegable al pasar el mouse:

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

En mi opinión, la mejor forma 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 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>

La mejor manera de hacerlo es simplemente activar el evento de clic de Bootstrap con un desplazamiento. De esta forma, debería seguir siendo compatible con dispositivos táctiles.

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

Lo he logrado de la siguiente manera:

$('ul.nav li.dropdown').hover(function(){
       $(this).children('ul.dropdown-menu').slideDown(); 
    }, function(){
       $(this).children('ul.dropdown-menu').slideUp(); 
});

Espero que esto ayude a alguien...

También se agregó margin-top: 0 para restablecer el margen CSS de bootstrap para .dropdown-menu para que la lista del menú no desaparezca cuando el usuario pasa lentamente del menú desplegable a la lista del menú.

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

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

Probablemente sea una idea estúpida, pero para eliminar la flecha que apunta hacia abajo, puede eliminar la

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

Sin embargo, esto no hace nada para el que apunta hacia arriba ...

He publicado un complemento adecuado para la funcionalidad de desplazamiento del menú desplegable Bootstrap 3, en el que incluso puede definir lo que sucede al hacer clic en el dropdown-toggleelemento (el clic se puede deshabilitar):

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 usando 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á para volver a aparecer. Algunas de las soluciones 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 creé el complemento Bootstrap Dropdown Hover que evita todos estos problemas utilizando solo la API estándar de JavaScript de Bootstrap, sin ningún tipo de pirateo . Incluso los atributos de Aria funcionan bien con este complemento.

Esto también puede hacer eso.


$('.dropdown').on('mouseover',function(){
    $(this).find('.dropdown-menu').show();
});
$('.dropdown').on('mouseleave',function(){
    $(this).find('.dropdown-menu').hide();
});

Si el menú desplegable tiene un espacio entre el elemento suspendido, el menú desplegable se cerrará inmediatamente como se ve en este GIF

El menú desplegable se oculta tan pronto como se borra el elemento.

Para evitar este comportamiento, puede agregar un tiempo de espera a los eventos de 100ms

let dropdownTimer;
$('.dropdown').on('mouseover', () => {
    clearTimeout(dropdownTimer)
    $(this).find('.dropdown-menu').show();
});
$('.dropdown').on('mouseleave', () =>{
    dropdownTimer = setTimeout(() => {
        $(this).find('.dropdown-menu').hide();
    }, 100)
});

Menú desplegable que se mantiene abierto durante un tiempo de espera establecido

Use este código para abrir el submenú al pasar el mouse (solo escritorio):

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

Y si desea que se pueda hacer clic en el menú de primer nivel, incluso en dispositivos móviles, agregue esto:

    $('.dropdown-toggle').click(function() {
    if ($(this).next('.dropdown-menu').is(':visible')) {
        window.location = $(this).attr('href');
    }
});

El submenú (menú desplegable) se abrirá con el mousehover en el escritorio y con clic / toque en el móvil y la tableta. Una vez que se abrió el submenú, un segundo clic le permitirá abrir el enlace. Gracias a if ($(window).width() > 767), el submenú ocupará todo el ancho de la pantalla en el móvil.

$('.dropdown').hover(function(e){$(this).addClass('open')})

Esto funciona para Bootstrap V4

JS:

<script>
        $(function() {
            $('.dropdown-hover').hover(
                function() { $(this).addClass('show'); $(this).find('[data-toggle="dropdown"]').attr('aria-expanded', true); $(this).find('.dropdown-menu').addClass('show'); },
                function() { $(this).removeClass('show'); $(this).find('[data-toggle="dropdown"]').attr('aria-expanded',false); $(this).find('.dropdown-menu').removeClass('show'); }
            );
        });
    </script>

Vanilla Bootstrap 4 Dropdown HTML, excepto por la adición de la clase desplegable-hover:

<div class="dropdown dropdown-hover">
<button class="btn btn-text dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    ABOUT
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
</div>

Si no desea habilitar selectivamente la función de desplazamiento mediante el uso de la clase .dropdown-hover, simplemente cambie el selector de jquery de .dropdown-hover a .dropdown.

Esto ocultará a los que están arriba

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

Esto debería ocultar los menús desplegables y sus signos de intercalación si son más pequeños que una tableta.

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

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 alguna detección de cambio de tamaño de 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;
    }
}

La solución muy simple para la versión 2, solo CSS. Mantiene la misma funcionalidad amigable para dispositivos móviles y tabletas.

@media (min-width: 980px) {
    .dropdown:hover .dropdown-menu {
       display: block;
    }
}

Sobrescriba bootstrap.js con 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') })
});

}); 

Esta es mi técnica que agrega un ligero retraso antes de que se cierre el menú después de que dejas de desplazarte por el menú o el botón de alternancia. El <button>que normalmente haría clic para mostrar el menú de navegación es #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);
});

Para mejorar la respuesta de Sudharshan, envuelvo esto en una consulta de medios para evitar el desplazamiento cuando se usa el ancho 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 signo de intercalación en el marcado, solo la clase desplegable para li .