Liste déroulante Bootstrap avec survol

179

OK, donc ce dont j'ai besoin est assez simple.

J'ai mis en place une barre de navigation avec des menus déroulants (en utilisant class="dropdown-toggle" data-toggle="dropdown"), et cela fonctionne très bien.

Le truc, c'est que ça marche " onClick", alors que je préférerais que ça marche " onHover".

Existe-t-il un moyen intégré de le faire?

Dr Kameleon
la source
Voir mon plugin approprié nouvellement publié qui empêche les problèmes des solutions CSS et js ci-dessous: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Réponses:

338

La solution la plus simple serait en CSS. Ajoutez quelque chose comme ...

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

Violon de travail

brbcoding
la source
3
Tellement mieux que de longues solutions «complètes». Ajoutez simplement ceci et le menu déroulant par défaut `` clic '' fonctionne en survol sans modifications supplémentaires.
IamFace
47
Cela entrera en conflit avec le menu mobile pliable intégré, vous devez donc l'envelopper dans un point de rupture @media (largeur min: 480px)
Billy Shih
7
A noter également: si vous avez un menu déroulant avec des relations parent-enfant, par exemple dans un thème wordpress, vous devez supprimer l' data-toggleattribut pour rendre l'élément parent cliquable ... Il suffit de faire attention aux dommages collatéraux sur les écrans mobiles.
Ken Prince
2
Existe-t-il un moyen simple de désactiver l'affichage au clic et de conserver uniquement le comportement de survol?
Micer
1
@Micer, je viens de publier un plugin dans lequel vous pouvez désactiver l'événement de clic. Le plugin fonctionne sans aucun hack CSS, en utilisant uniquement l'API javascript Bootstrap, il est donc compatible avec tous les appareils: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros
66

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

$('.dropdown').hover(function(){ 
  $('.dropdown-toggle', this).trigger('click'); 
});
Mark Williams
la source
1
échoue si vous avez plus d'un niveau déroulant
Connie DeCinko
1
Ne fonctionne pas avec le lien parent
pio
existe-t-il un moyen de supprimer la classe Active une fois la liste déroulante fermée?
brainvision
Il y a un espace de pixels entre l'élément déroulant et le menu qui peut faire en sorte que le menu se cache parfois, à moins que vous ne soyez rapide
Matt
1
L'utilisation de plusieurs listes déroulantes nécessite un filtrage «le plus proche».
err
57

Vous pouvez utiliser la fonction de survol de jQuery.

Il vous suffit d'ajouter la classe openlorsque la souris entre et de supprimer la classe lorsque la souris quitte la liste déroulante.

Voici mon code:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});
adhi
la source
10
Bien mieux que la réponse acceptée à mon humble avis. Cela garde toute la logique et le style du bootstrap intacts. Bien que je vous conseille d'utiliser le deuxième rappel et d'utiliser explicitement removeClass et addClass pour éviter certains comportements bizarres lorsque vous avez cliqué sur le bouton (où il s'ouvrirait lorsque vous quitteriez le bouton et se fermerait lorsque vous l'entreriez).
Bastiaan Linders
3
Je pense aussi que c'est la meilleure réponse. Pour le faire fonctionner avec le menu Bootstrap 4, j'ai dû utiliser à la showplace de open, et également inclure le dropdown-menu: $('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(Désolé pour le formatage.)
Robin Zimmermann
Ne fonctionne pas si vous avez deux éléments de menu déroulant. En survolant n'importe quel élément de la liste déroulante, les deux sous
Juan Antonio Tubío
23

Un moyen simple, en utilisant jQuery, est le suivant:

$(document).ready(function(){
    $('ul.nav li.dropdown').hover(function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(200);
    }, function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(200);
    });  
});
Biagio Chirico
la source
J'adore la transition en douceur, mais cela entraîne l'expansion de tous les niveaux de menu au lieu du premier niveau. Je ne veux pas que les menus de deuxième niveau apparaissent jusqu'à ce que je survole leur parent.
Connie DeCinko
1
Pour obtenir le premier niveau uniquement, ajoutez .first() - $(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);...
JEdot
9

Pour CSS, cela devient fou lorsque vous cliquez également dessus. C'est le code que j'utilise, cela ne change rien non plus pour la vue mobile.

$('.dropdown').mouseenter(function(){
    if(!$('.navbar-toggle').is(':visible')) { // disable for mobile view
        if(!$(this).hasClass('open')) { // Keeps it open when hover it again
            $('.dropdown-toggle', this).trigger('click');
        }
    }
});
user1079877
la source
Une beauté! Tx! Les alternatives CSS ne fonctionneront pas sur Bootstrap 3 et au-delà.
Pedro Ferreira du
5

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 l'événement de clic, et vous voulez qu'il fonctionne sur l'é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 quittons le bouton, nous masquons le menu après 100 ms. Si vous vous demandez pourquoi j'utilise cela, c'est parce que vous avez besoin de temps pour faire glisser le curseur du bouton sur le menu. Lorsque vous êtes dans le 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 masquerons le menu instantanément sans aucun délai.

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

Crisan Raluca Teodora
la source
Ce code a beaucoup de problèmes sur bootstrap v3. 1.) S'il y a plus d'une liste déroulante, toutes les listes déroulantes sont affichées lorsque l'une d'entre elles est survolée. 2.) Sur les petits écrans, le survol montre la liste déroulante d'une manière étrange.
KayakinKoder
4

C'est ce que j'utilise pour faire une liste déroulante en survol avec du jQuery

$(document).ready(function () {
    $('.navbar-default .navbar-nav > li.dropdown').hover(function () {
        $('ul.dropdown-menu', this).stop(true, true).slideDown('fast');
        $(this).addClass('open');
    }, function () {
        $('ul.dropdown-menu', this).stop(true, true).slideUp('fast');
        $(this).removeClass('open');
    });
});
Amir5000
la source
Nice mais ne prend pas en charge les sous-menus.
Connie DeCinko
3

Essayez ceci en utilisant la fonction de survol avec des animations de fondu en fondu

$('ul.nav li.dropdown').hover(function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);
}, function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);
});
Rakesh Vadnal
la source
Cette animation ne fonctionne pas en 3ème profondeur mais en 2ème profondeur. Avez-vous une autre solution pour la 3e profondeur?
Jilani A
Veuillez ajouter JSFiddle pour référence
Rakesh Vadnal
2

Cela vous aidera à créer votre propre classe de survol pour bootstrap:

CSS:

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

Les marges sont définies pour éviter la fermeture indésirable et elles sont facultatives.

HTML:

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

N'oubliez pas de supprimer l'attribut de bouton data-toggle = "dropdown" si vous souhaitez supprimer un clic ouvert, et cela fonctionnera également lorsque l'entrée est ajoutée avec une liste déroulante.

Sabri Aziri
la source
2

Cela ne fait que survoler la barre de navigation lorsque vous n'êtes pas sur un appareil mobile, car je trouve que le survol de la navigation ne fonctionne pas bien sur les appareils mobiles:

    $( document ).ready(function() {

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

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

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

});
solarbaypilot
la source
Vous pouvez trouver une bien meilleure solution ici: github.com/CWSpear/bootstrap-hover-dropdown .
solarbaypilot
2

J'essaie d'autres solutions, j'utilise bootstrap 3, mais le menu déroulant se ferme trop rapidement pour passer dessus

supposé que vous ajoutiez class = "dropdown" à li, j'ai ajouté un timeout

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

Mis à jour avec un plugin approprié

J'ai publié un plugin approprié pour la fonctionnalité de survol de la liste déroulante, dans lequel vous pouvez même définir ce qui se passe lorsque vous cliquez sur l' dropdown-toggleélément:

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


Pourquoi je l'ai fait, alors qu'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 .openclasse sur le .dropdown, il n'y aura donc aucun retour sur l'élément bascule de la liste déroulante lorsque la liste déroulante est visible.

Les js interfèrent avec le clic 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, et le déplacement de la souris déclenchera la liste déroulante pour réapparaître. Certaines des solutions js freinent 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 évite tous ces problèmes en utilisant uniquement l'API javascript Bootstrap standard, sans aucun hack.

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

Le déclenchement d'un clickévénement avec un hovera une petite erreur. Si mouse-inet puis a clickcrée un effet vice-versa. C'est opensquand mouse-outet closequand mouse-in. Une meilleure solution:

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

html

        <div class="dropdown">

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

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

        </div> 

jquery

        $(document).ready( function() {                

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

        });

codepen

antelove
la source
0

La solution que je propose détecte si son appareil n'est pas tactile et que le navbar-toggle(menu hamburger) n'est pas visible et rend l'élément de menu parent révélant le sous-menu au survol et et suit son lien au clic .

Rend également la marge supérieure à 0 car l'écart entre la barre de navigation et le menu dans certains navigateurs ne vous permettra pas de survoler les sous-éléments

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

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

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

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

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

GiorgosK
la source
0

Liste déroulante Bootstrap Travaillez au survol, et restez fermé au clic en ajoutant la propriété display: block; en css et en supprimant ces attributs data-toggle = "dropdown" role = "button" de la balise button

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

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

</body>
</html>

Super modèle
la source