web-dev-qa-db-fra.com

Comment rendre Twitter Bootstrap menu déroulant en survol plutôt que de cliquer

J'aimerais que mon menu Bootstrap défile automatiquement en survol, plutôt que de devoir cliquer sur le titre du menu. J'aimerais aussi perdre les petites flèches à côté des titres de menu.

1131
falter

J'ai créé un menu déroulant pur lors du survol basé sur le dernier (_2.0.2) Bootstrap framework prenant en charge plusieurs sous-menus et j'ai pensé le publier pour les futurs utilisateurs:

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>

démo

571
Andres Ilich

Pour que le menu disparaisse automatiquement en survol, cela peut être réalisé à l'aide de CSS de base. Vous devez définir le sélecteur sur l'option de menu masqué, puis le configurer pour qu'il s'affiche sous forme de bloc lorsque la balise li appropriée est survolée. En prenant l'exemple de la page Twitter bootstrap, le sélecteur serait le suivant:

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

Toutefois, si vous utilisez les fonctionnalités réactives de Bootstrap, vous ne voudrez pas cette fonctionnalité sur une barre de navigation réduite (sur des écrans plus petits). Pour éviter cela, placez le code ci-dessus dans une requête multimédia:

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

Pour masquer la flèche (curseur), cela se fait de différentes manières selon que vous utilisiez Twitter Bootstrap version 2 et antérieure ou version 3:

Bootstrap 3

Pour supprimer le curseur dans la version 3, il vous suffit de supprimer l'élément HTML <b class="caret"></b> de l'élément d'ancrage .dropdown-toggle:

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

Bootstrap 2 et inférieur

Pour supprimer le curseur dans la version 2, vous avez besoin d'un peu plus de perspicacité dans CSS. Je suggère de regarder comment le pseudo-élément :after fonctionne plus en détail. Pour vous aider à comprendre, à cibler et à supprimer les flèches de l'exemple Twitter bootstrap, utilisez le sélecteur et le code CSS suivants:

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

Cela fonctionnera en votre faveur si vous étudiez plus en profondeur la manière dont cela fonctionne et ne vous contentez pas d'utiliser les réponses que je vous ai données.

Merci à @CocaAkat d'avoir signalé l'absence du combinateur enfant ">" pour empêcher l'affichage des sous-menus sur le survol du parent

901
My Head Hurts

En plus de la réponse de "My Head Hurts" (qui était super):

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

Il y a 2 problèmes en suspens:

  1. En cliquant sur le lien déroulant, vous ouvrez le menu déroulant. Et il restera ouvert à moins que l'utilisateur ne clique quelque part ou ne le survole, créant une interface utilisateur gênante.
  2. Il y a une marge de 1 px entre le lien déroulant et le menu déroulant. Cela fait que le menu déroulant devient masqué si vous vous déplacez lentement entre le menu déroulant et le menu déroulant.

La solution à (1) est de supprimer les éléments "class" et "data-toggle" du lien de navigation

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

Cela vous donne également la possibilité de créer un lien vers votre page parent - ce qui n'était pas possible avec l'implémentation par défaut. Vous pouvez simplement remplacer le "#" par la page que vous souhaitez envoyer à l'utilisateur.

La solution à (2) consiste à supprimer le haut de la marge sur le sélecteur de menu déroulant.

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

J'ai utilisé un peu 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();
});
127
John Montgomery

Il y a beaucoup de très bonnes solutions ici. Mais je pensais que j'allais y aller et mettre le mien ici comme une autre alternative. C'est juste un simple fragment jQuery qui le fait comme bootstrap s'il prend en charge le survol pour les menus déroulants au lieu de simplement cliquer. J'ai seulement testé cela avec la version 3, donc je ne sais pas si cela fonctionnerait avec la version 2. Enregistrez-le en tant qu'extrait dans votre éditeur et placez-le au passage d'une touche.

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

En gros, cela signifie simplement que lorsque vous passez la souris sur une classe déroulante, elle y ajoute la classe ouverte. Alors ça marche. Lorsque vous arrêtez de survoler le lien parent avec la classe de liste déroulante ou celui des enfants/li, il supprime la classe ouverte. De toute évidence, il ne s’agit que d’une solution parmi de nombreuses autres et vous pouvez l’ajouter pour qu’elle ne fonctionne que sur des instances spécifiques de .dropdown. Ou ajoutez une transition à un parent ou à un enfant.

69
stereoscience

Personnalisez simplement votre style CSS en trois lignes de code

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

Si vous avez un élément avec une classe dropdown comme celle-ci (par exemple):

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

Ensuite, vous pouvez avoir le menu déroulant pour être automatiquement déroulé en survol, plutôt que d'avoir à cliquer sur son titre, en utilisant cet extrait de code 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>

Voici une démo

Cette réponse s'appuyait sur @ Michael réponse , j'ai apporté des modifications et ajouté des ajouts pour que le menu déroulant fonctionne correctement

22
Amr

[Mise à jour] Le plugin est activé GitHub et je travaille sur quelques améliorations (comme utiliser uniquement avec des attributs de données (non JS nécessaire). J'ai laissé le code ci-dessous, mais ce n'est pas la même chose que ce qui est sur GitHub.

J'ai bien aimé la version purement CSS, mais c'est agréable d'avoir un délai avant la fermeture, car c'est généralement une meilleure expérience utilisateur (c'est-à-dire non punie pour un glissement de souris qui sort de 1 px en dehors du menu déroulant, etc.), et comme mentionné dans les commentaires , il y a 1px de marge que vous devez gérer ou parfois la navigation se ferme de manière inattendue lorsque vous passez au menu déroulant depuis le bouton d'origine, etc.

J'ai créé un petit plugin rapide que j'ai utilisé sur quelques sites et qui a bien fonctionné. Chaque élément de navigation est géré indépendamment, de sorte qu'il possède son propre délai, 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);
        });
    });
};  

Le paramètre delay est assez explicite, et le instantlyCloseOthers ferme instantanément toutes les autres listes déroulantes ouvertes lorsque vous survolez une nouvelle.

Ce n'est pas du pur CSS, mais j'espère que cela aidera quelqu'un d'autre à cette heure tardive (c'est-à-dire qu'il s'agit d'un vieux fil).

Si vous le souhaitez, vous pouvez voir les différents processus que j'ai suivis (dans une discussion sur le #concrete5 IRC) pour le faire fonctionner via les différentes étapes de ce Gist: https: //Gist.github .com/3876924

L’approche des modèles de plug-ins est beaucoup plus propre pour prendre en charge des minuteries individuelles, etc.

Voir le blog post pour plus.

20
CWSpear

Cela a fonctionné pour moi:

.dropdown:hover .dropdown-menu {
    display: block;
}
15
Amay Kulkarni

Ceci est intégré à Bootstrap 3. Ajoutez simplement ceci à votre CSS:

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

Encore mieux avec 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');
});
10
caarlos0

Vous pouvez utiliser la méthode par défaut $().dropdown('toggle') pour basculer le menu déroulant en survol:

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

Je veux juste ajouter que si vous avez plusieurs listes déroulantes (comme je le fais), vous devez écrire:

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

Et ça va fonctionner correctement.

8
Maxim Filippov

La meilleure façon de le faire est de simplement déclencher l'événement click de Bootstrap avec un survol. De cette façon, il devrait toujours rester convivial pour les appareils tactiles.

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

À mon avis, le meilleur moyen est le suivant:

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

Échantillon de balisage:

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

Je l'ai géré comme suit:

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

J'espère que ça aidera quelqu'un...

7
Mehdi Maghrooni

De plus, margin-top: 0 a été ajouté pour réinitialiser la marge bootstrap css pour .dropdown-menu afin que la liste des menus ne disparaisse pas lorsque l'utilisateur passe lentement du menu déroulant à la liste des menus.

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

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

C’est probablement une idée stupide, mais pour supprimer la flèche pointant vers le bas, vous pouvez supprimer le

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

Cela ne fait rien pour la hausse, cependant ...

5
stinaq

J'ai publié un plugin approprié pour la fonctionnalité de survol déroulant Bootstrap 3, dans lequel vous pouvez même définir ce qui se passe lorsque vous cliquez sur le bouton de la souris. Elément dropdown-toggle (le clic peut être désactivé):

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


Pourquoi je l'ai fait quand il y a déjà beaucoup de solutions?

J'ai eu des problèmes avec toutes les solutions existantes. Les CSS simples n'utilisent pas la classe .open sur le .dropdown, il n'y aura donc pas de retour sur l'élément à bascule déroulant lorsque celui-ci sera visible.

Les js interfèrent en cliquant sur .dropdown-toggle, de sorte que la liste déroulante apparaît en survol, puis la masque lorsque vous cliquez sur une liste déroulante ouverte. Le déplacement de la souris déclenche la réapparition de la liste déroulante. Certaines des solutions js rompent la compatibilité iOS, certains plugins ne fonctionnent pas sur les navigateurs de bureau modernes qui prennent en charge les événements tactiles.

C'est pourquoi j'ai créé le plugin Bootstrap Dropdown Hover qui empêche tous ces problèmes en utilisant à l'aide de uniquement l'API javascript Bootstrap _ standard, sans aucun piratage . Même les attributs Aria fonctionnent bien avec ce plugin.

5

Utilisez ce code pour ouvrir le sous-menu sur mousehover (sur le bureau uniquement):

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

Et si vous voulez que le menu de premier niveau soit cliquable, même sur mobile, ajoutez ceci:

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

Le sous-menu (menu déroulant) s'ouvrira avec mousehover sur le bureau et avec click/touch sur le mobile et la tablette. Une fois le sous-menu ouvert, un deuxième clic vous permettra d’ouvrir le lien. Grâce à la if ($(window).width() > 767), le sous-menu occupe toute la largeur de l'écran.

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

Cela va cacher les haut

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

La solution jQuery est bonne, mais il faudra soit gérer les événements au clic (pour les mobiles ou les tablettes), car le survol ne fonctionnera pas correctement ... Vous pourriez peut-être effectuer une détection de la taille de la fenêtre?

La réponse d'Andres Ilich semble bien fonctionner, mais elle devrait être résumée dans une requête 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
Fizex

Cela devrait masquer les menus déroulants et leurs caractères s'ils sont plus petits qu'une tablette.

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

Pour améliorer réponse de Sudharshan , je l'enveloppe dans une requête de média pour empêcher le survol lorsque les largeurs d'affichage XS ...

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

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

De plus, le signe d'insertion dans le balisage n'est pas obligatoire, mais uniquement la classe déroulante pour le li .

2
johna

Donc vous avez ce code:

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

Normalement, cela fonctionne sur un événement de clic et vous voulez que cela fonctionne sur un événement de survol. C'est très simple, utilisez simplement ce code 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();
        })
    })
})

Cela fonctionne très bien et voici l'explication: nous avons un bouton et un menu. Lorsque nous survolons le bouton, nous affichons le menu et lorsque nous laissons la souris sur le bouton, nous masquons le menu au bout de 100 ms. Si vous vous demandez pourquoi je l’utilise, c’est parce que vous avez besoin de temps pour faire glisser le curseur du bouton sur le menu. Lorsque vous êtes au menu, l'heure est réinitialisée et vous pouvez y rester autant de fois que vous le souhaitez. Lorsque vous quittez le menu, nous le masquons instantanément sans délai d'expiration.

J'ai utilisé ce code dans de nombreux projets. Si vous rencontrez un problème, n'hésitez pas à me poser des questions.

2

Voici ma technique qui ajoute un léger délai avant la fermeture du menu lorsque vous arrêtez de vous déplacer sur le menu ou le bouton bascule. Le <button> sur lequel vous devez normalement cliquer pour afficher le menu de navigation est #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
Sarah Vessels

Remplacez bootstrap.js avec ce 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
Hari Krishnan

Pour le caret ... Je n'ai vu personne spécifiant un CSS simple bloquant totalement le curseur.

Voici:

.caret {
    display: none !important;
}
2
Restartit Fbapp

Cela fonctionne pour WordPress Bootstrap:

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

La solution très simple pour la version 2, uniquement CSS. Conserve la même fonctionnalité conviviale pour mobile et tablette.

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

Voici le JSFiddle -> https://jsfiddle.net/PRkonsult/mn31qf0p/1/

Le bit JavaScript en bas est ce qui fait la magie réelle.

HTML

<!--http://getbootstrap.com/components/#navbar-->
<div class="body-wrap">
  <div class="container">
    <nav class="navbar navbar-inverse" role="navigation">
      <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Brand</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Link</a></li>
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
              <ul class="dropdown-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><a href="#">Separated link</a></li>
                <li class="divider"></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
          </ul>

          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
              <ul class="dropdown-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><a href="#">Separated link</a></li>
              </ul>
            </li>
          </ul>
        </div>
        <!-- /.navbar-collapse -->
      </div>
      <!-- /.container-fluid -->
    </nav>
  </div>
</div>

CSS

/* Bootstrap dropdown hover menu */

body {
  font-family: 'PT Sans', sans-serif;
  font-size: 13px;
  font-weight: 400;
  color: #4f5d6e;
  position: relative;
  background: rgb(26, 49, 95);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(26, 49, 95, 1)), color-stop(10%, rgba(26, 49, 95, 1)), color-stop(24%, rgba(29, 108, 141, 1)), color-stop(37%, rgba(41, 136, 151, 1)), color-stop(77%, rgba(39, 45, 100, 1)), color-stop(90%, rgba(26, 49, 95, 1)), color-stop(100%, rgba(26, 49, 95, 1)));
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#1a315f', endColorstr='#1a315f', GradientType=0);
}

.body-wrap {
  min-height: 700px;
}

.body-wrap {
  position: relative;
  z-index: 0;
}

.body-wrap: before,
.body-wrap: after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: -1;
  height: 260px;
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(26, 49, 95, 1)), color-stop(100%, rgba(26, 49, 95, 0)));
  background: linear-gradient(to bottom, rgba(26, 49, 95, 1) 0%, rgba(26, 49, 95, 0) 100%);
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#1a315f', endColorstr='#001a315f', GradientType=0);
}

.body-wrap:after {
  top: auto;
  bottom: 0;
  background: linear-gradient(to bottom, rgba(26, 49, 95, 0) 0%, rgba(26, 49, 95, 1) 100%);
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#001a315f', endColorstr='#1a315f', GradientType=0);
}

nav {
  margin-top: 60px;
  box-shadow: 5px 4px 5px #000;
}

Ensuite, le bit important de code JavaScript:

$('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);
});
2
Erik Thiart

Cela fonctionne pour 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 HTML dropdown sauf pour l'ajout de la classe dropdown-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 vous ne souhaitez pas activer la fonctionnalité de survol de manière sélective à l'aide de la classe .dropdown-hover, il vous suffit de changer le sélecteur JQuery de .dropdown-hover à .dropdown.

2
Drew

Ajouter ceci pour ceux qui veulent une fonctionnalité par défaut sur les appareils mobiles. Peut définir min-width: ... comme requis

@media only screen and (min-width: 1195px) {
  ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;
  }
  ul.nav li.dropdown> ul.dropdown-menu {
    display: none;
  }
}

régler display: none pour que dropdown-toggle ne crée pas de problème. Si vous le laissez tel quel, il se peut que deux listes déroulantes s’ouvrent en même temps.

0
maestar

Solution Bootstrap v4 - Fonctionne dans IE

Cela vous permettra de suivre les liens de navigation de haut niveau.

C'est une solution complète qui utilise les événements mouseover et mouseleave et certaines vérifications de la largeur de l'écran.

Cela a été construit avec ordinateur de bureau et mobile à l'esprit. N'hésitez pas à modifier la variable BREAK_POINT selon vos besoins: D.

jQuery

var WINDOW_WIDTH;
var BREAK_POINT = 991;

(function ($) {

    /** Set window width onload */
    WINDOW_WIDTH = $(window).width(); // Returns width of browser viewport
    /** Set window width if the browser is resized */
    $(window).resize(function () {
        WINDOW_WIDTH = $(window).width(); // Returns width of browser viewport
    });

    /** Dropdown menu on mouseenter */
    $(".nav-item.dropdown").on('mouseenter', function () {
        console.log("mouseenter");
        if (WINDOW_WIDTH >= BREAK_POINT) {
            // Open up the dropdown
            $(this).addClass('show'); // add the class show to the li parent
            $(this).children('.nav-link').removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link
            $(this).children('.dropdown-menu').addClass('show'); // add the class show to the dropdown div sibling
        }
    });
    /** Dropdown menu on mouseleave */
    $(".nav-item.dropdown").on('mouseleave', function () {
        console.log("mouseleave");
        if (WINDOW_WIDTH >= BREAK_POINT) {
            // Open up the dropdown
            $(this).removeClass('show'); // add the class show to the li parent
            $(this).children('.nav-link').attr('data-toggle', 'dropdown'); // remove the data-toggle attribute so we can click and follow link
            $(this).children('.dropdown-menu').removeClass('show'); // add the class show to the dropdown div sibling
        }
    });
});

CSS

@media(min-width:  768px) {
  .dropdown-menu {
    margin-top: 0; // fixes closing on slow mouse transition
  }
}
0
Radmation

La réponse la plus standard:

  • Prend en charge l'attribut aria-expand
  • Prend en charge les appareils non tactiles
  • Prend en charge les appareils tactiles
  • Prend en charge toutes les listes déroulantes
var isTouchDevice =
    (('ontouchstart' in window) ||
    (navigator.MaxTouchPoints > 0) ||
    (navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
    // open dropdowns on hover on non mobile devices
    $(".dropdown").hover(function() {
        $('.dropdown-toggle', this).dropdown("toggle");
    });
}

Vous pouvez remplacer $(".dropdown") par une zone spécifique si vous avez besoin de:

$("#top-menu .dropdown")
0
Farhad Sakhaei

Bootstrap 4, 2019

J'ai lu beaucoup de réponses mais j'ai fini par le faire moi-même parce que ce n'était tout simplement pas ce dont j'avais besoin.

J'ai Bootstrap 4, et je veux garder le clic + le survol fonctionnalité. En outre, je souhaite l’activer uniquement dans les menus déroulants qui ont une classe supplémentaire ".open-on-hover".

Je souhaite également conserver la Jquery de Bootstrap qui positionne la liste déroulante lorsqu'elle se trouve à côté du bord de la page. Donc, nous ne voulons pas simplement faire "display: block". Nous voulons la méthode de travail complète de Bootstrap. Je déclenche donc simplement le clic.

La logique est la suivante: "S'il s'agit d'un mouseenter, ouvrez-le. Si c'est un déplacé de souris, masquez-le s'il est ouvert"

/**
 * Open Bootstrap 4 dropdown on hover
 */
$(document).on('mouseenter mouseleave', '.dropdown.open-on-hover', function(e) 
{
    let toggler = $(this).find('[data-toggle="dropdown"]').first();

    if(e.type === 'mouseenter') {
        $(toggler).trigger('click', 'open');
    } else if ($(this).children('.dropdown-menu.show').length) {
        $(toggler).trigger('click', 'close');
    }
});

Le html

<div class="dropdown open-on-hover">
    <div class="btn" data-toggle="dropdown">
        Hover or click me
    </div>
    <div class="dropdown-menu">
        <a class="dropdown-item">
            Item 1
        </a>
        <a class="dropdown-item">
            Item 2
        </a>
    </div>
</div>
0
Julesezaar

J'espère que ça aide. Vérifiez le lien https://jsfiddle.net/awb7gfb1/

<nav>
    <div id="menubar" class=" collapse navbar-collapse row">
        <ul id="dropdownNavbar" class="nav navbar-nav">
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-time"></span>
                Time Card
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a id="showTimeCard" href="#">My Time Card</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                    <a href="#">Sub Menu 4</a>
                    <a href="#">Sub Menu 5</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-stats"></span>
                Project
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn"><span class="glyphicon glyphicon-user"></span>
                HR Links
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn">
                <span class="glyphicon glyphicon-screenshot"></span>
                Leave Tracker
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                    <a href="#">Sub Menu 4</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn">
                <span class="glyphicon glyphicon-briefcase"></span>
                Accounts
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                    <a href="#">Sub Menu 4</a>
                    <a href="#">Sub Menu 5</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn">
                <span class="glyphicon glyphicon-headphones"></span>
                Service Desk
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                    <a href="#">Sub Menu 4</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn">
                <span class="glyphicon glyphicon-file"></span>
                Reports
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                    <a href="#">Sub Menu 4</a>
                    <a href="#">Sub Menu 5</a>
                </div>
            </li>
            <li class="dropdown">
                <button type="button" class="btn btn-primary dropbtn">
                <span class="glyphicon glyphicon-cog"></span>
                Settings
                <span class="caret"></span></button>
                <div class="dropdown-content">
                    <a href="#">Sub Menu 1</a>
                    <a href="#">Sub Menu 2</a>
                    <a href="#">Sub Menu 3</a>
                </div>
            </li>
        </ul>
    </div>
</nav>

Et le CSS

.dropdown {
    float: left;
    padding-right: 1px;
}

.dropbtn{
    border: 0px;
    height: 30px;
    border-radius: 0px 10px;
}
li button, .dropbtn {
    display: inline-block;
    color: white;
    text-align: center;
}

li button:hover, .dropdown:hover .dropbtn {
    background-color: #12A5F4;
}

.dropbtn.active {
    background: #12A5F4;
}

.dropdown-content {
    display: none;
    position: absolute;
    background-color: #e8f3f4;
    min-width: 100%;
    box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
    z-index: 10;
}

.navbar-header{
    overflow: visible;
    z-index: 1;
}

.dropdown-content a {
    color: black;
    padding: 5px 10px;
    display: block;
    text-align: left;
}

.dropdown-content a:hover {
    background-color: #d8dee2
}

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

#menubar{
    padding-top: 5px;
    overflow: visible;
    z-index: 10;
    padding-left: 0px;
    padding-right: 0px;
    margin: 0px;
}

#dropdownNavbar{
    margin: 0px;
}

.navbar-toggle{
    background-color: #3382d5;
}
.navbar-toggle span{
    background-color: white;
}
0
Ankur Sahu
 <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-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><a href="#">Separated link</a></li>
            <li class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <script>
        $('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);
        });
      </script>
0
shiva krishna

Utilisez deux liens en ligne. Cachez le lien avec la bascule déroulante et ajoutez l'événement onmouseover au-dessus du lien visible pour cliquer sur le menu déroulant.

<a class="pretty-button"
   href="#" alt="Notifications"
   onmouseover="$('#notifications-dropdown').click()">
</a>

<a style="display:none"
   id="notifications-dropdown"
   class="js-nav js-tooltip js-dynamic-tooltip"
   href="#"
   alt="Notifications"
   data-toggle="dropdown">
   <span class="fa fa-flag fa-2x"></span>
</a>
0
F.O.O
<!DOCTYPE html>
<html>
<head>
<style>
.dropbtn {
    background-color: #4CAF50;
    color: white;
    padding: 16px;
    font-size: 16px;
    border: none;
    cursor: pointer;
}

.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    background-color: #f9f9f9;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
}

.dropdown-content a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

.dropdown-content a:hover {background-color: #f1f1f1}

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

.dropdown:hover .dropbtn {
    background-color: #3e8e41;
}
</style>
</head>
<body>

<h2>Hoverable Dropdown</h2>
<p>Move the mouse over the button to open the dropdown menu.</p>

<div class="dropdown">
  <button class="dropbtn">Dropdown</button>
  <div class="dropdown-content">
    <a href="#">Link 1</a>
    <a href="#">Link 2</a>
    <a href="#">Link 3</a>
  </div>
</div>

</body>
</html>
0
Ahmad

Nous avons vu, En plus de la réponse de " Ma tête me fait mal ", " Cory Price "a découvert deux problèmes:

Problème 1: Cliquez sur le lien déroulant pour ouvrir le menu déroulant. Et il restera ouvert à moins que l'utilisateur ne clique quelque part ou ne le survole, créant une interface utilisateur gênante.

Solution: Supprimer les éléments "class" et "data-toggle" du lien de navigation

La solution était presque parfaite, mais le problème est que, lorsqu'il s'agit d'appareils mobiles et de tablettes, cela ne fonctionnera pas!

J'utilise un peu de code jQuery pour résoudre ce problème ..

if ($(window).width() > 769) {
    $('.dropdown-toggle').removeAttr('data-toggle');
    $('.dropdown-menu').removeAttr('style');
    $('.dropdown').removeClass('open');
}
$(window).resize(function () {
    if ($(window).width() > 769) {
        $('.dropdown-toggle').removeAttr('data-toggle');
        $('.dropdown-menu').removeAttr('style');
        $('.dropdown').removeClass('open');
    }
    else {
        $('.dropdown-toggle').attr("data-toggle", "dropdown");
    }
});

Note: Ici, nous supposons que la réduction pour les appareils mobiles et les tablettes est à partir de 768px.

0
Sobin Augustine