Come rendere il menu a discesa Twitter Bootstrap al passaggio del mouse anziché fare clic


1183

Vorrei che il mio menu Bootstrap scendesse automaticamente al passaggio del mouse, anziché fare clic sul titolo del menu. Vorrei anche perdere le piccole frecce accanto ai titoli dei menu.


9
C'è una soluzione per questo, quindi la risposta di mikko è corretta ma ora è coperta da un plugin specifico per quella situazione. bootstrap-hover-dropdown
HenryW

2
Guarda il mio plugin appena pubblicato che previene i problemi delle soluzioni CSS e js di seguito e funziona perfettamente su iOS e sui browser desktop moderni con eventi touch. Anche gli attributi di aria stanno funzionando bene con quello: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Ho creato un menu a discesa CSS3 puro con una barra di navigazione bootstrap verificalo sul menu a discesa
Gothburz,

18
Pensaci due volte se ne hai davvero bisogno? Bootstrap sta usando per siti adattivi. Significa che verranno utilizzati anche su dispositivi con controlli touch. Ecco perché è progettato in questo modo. Non c'è "passaggio del mouse" sui touchscreen.
Serj

Possibile duplicato di
Dropstrap Dropdown

Risposte:


592

Ho creato un menu a discesa puro al passaggio del mouse basato sull'ultimo (v2.0.2) framework Bootstrap che ha il supporto per più sottomenu e ho pensato di pubblicarlo per i futuri utenti:

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>

dimostrazione


54
è una decisione di progettazione in bootstrap di non aprire i menu a discesa sull'evento hover ...
caarlos0

18
così buono! Ho anche rimosso in class="dropdown-toggle" data-toggle="dropdown"modo che solo il passaggio del mouse, non il clic, attivasse il menu. Si noti che quando si utilizzano stili reattivi, i menu vengono comunque spostati nel piccolo pulsante in alto a destra, che viene comunque attivato da un clic. Grazie tante!
ptim,

11
Per evitare il calo automatico su dispositivi più piccoli (come i telefoni) e consentirlo solo a partire da una larghezza minima di 768 px @media (min-width: 768px) {.dropdown-menu li:hover .sub-menu {visibility: visible;}}e@media (min-width: 768px) {.dropdown:hover .dropdown-menu {display: block;}}
Chris Aelbrecht,

1
Inoltre, per rendere cliccabile il collegamento con i bambini, devi rimuovere "data-toggle = 'dropdown'" sul tag <a>.
joan16v,

2
Ecco un codice che funziona con l'ultima versione di Bootstrap 3: jsfiddle.net/sgruenwald/2tt8f8xg
Stefan Gruenwald

910

Per far cadere automaticamente il menu al passaggio del mouse, questo può essere ottenuto utilizzando CSS di base. È necessario elaborare il selettore sull'opzione di menu nascosta e quindi impostarlo per visualizzarlo come blocco quando si passa con il mouse sul litag appropriato . Prendendo l'esempio dalla pagina Twitter Bootstrap, il selettore sarebbe il seguente:

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

Tuttavia, se si utilizzano le funzionalità reattive di Bootstrap, non si desidera questa funzionalità su una barra di navigazione compressa (su schermi più piccoli). Per evitare ciò, avvolgere il codice sopra in una query multimediale:

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

Per nascondere la freccia (cursore) questo viene fatto in diversi modi a seconda che tu stia utilizzando Twitter Bootstrap versione 2 e precedenti o versione 3:

Bootstrap 3

Per rimuovere il cursore nella versione 3 devi solo rimuovere l'HTML <b class="caret"></b>dall'elemento .dropdown-toggleanchor:

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

Bootstrap 2 e precedenti

Per rimuovere il cursore nella versione 2 hai bisogno di un po 'più di approfondimento sui CSS e ti suggerisco di guardare come funziona lo :afterpseudo elemento in modo più dettagliato. Per iniziare a capire, indirizzare e rimuovere le frecce nell'esempio bootstrap di Twitter, utilizzare il seguente selettore e codice CSS:

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

Funzionerà a tuo favore se osservi ulteriormente come funzionano e non usi solo le risposte che ti ho dato.

Grazie a @CocaAkat per aver sottolineato che mancava il combinatore figlio ">" per impedire la visualizzazione dei sottomenu al passaggio del mouse del genitore


79
Inoltre margin: 0;, ho dovuto aggiungere , altrimenti il ​​margine di 1px sopra .dropdown-menuprovoca un comportamento errato.
Salman von Abbas,

12
Soluzione semplice, ma il collegamento principale non è ancora selezionabile. Sto usando l'ultimo bootstrap con il tema di root.
Krunal,

5
Nota: Sì, funziona: funziona con qualsiasi browser supportato da Twitter Bootstrap. @GeorgeEdison Questo è CSS di base - quale parte non sarebbe supportata da IE8? In caso di problemi, pubblica una domanda, non commenti fuorvianti.
Mi fa male la testa il

3
@MyHeadHurts: dopo alcune ulteriori ricerche - si è scoperto che questo era davvero un bug di Bootstrap ed è stato risolto solo cinque giorni fa.
Nathan Osman,

5
@Krunal per poter fare clic sul collegamento, è necessario rimuovere l' data-toggle="dropdown"attributo.
Pherrymason,

231

Oltre alla risposta di "My Head Hurts" (che è stato grandioso):

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

Ci sono 2 problemi persistenti:

  1. Facendo clic sul collegamento a discesa si aprirà il menu a discesa. E rimarrà aperto a meno che l'utente non faccia clic da qualche altra parte o ci passi sopra, creando un'interfaccia utente scomoda.
  2. C'è un margine di 1px tra il collegamento a discesa e il menu a discesa. In questo modo il menu a discesa viene nascosto se ci si sposta lentamente tra il menu a discesa e il menu a discesa.

La soluzione a (1) sta rimuovendo gli elementi "class" e "data-toggle" dal collegamento nav

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

Questo ti dà anche la possibilità di creare un link alla tua pagina principale, cosa impossibile con l'implementazione predefinita. Puoi semplicemente sostituire il "#" con qualunque pagina tu voglia inviare all'utente.

La soluzione a (2) sta rimuovendo il margine superiore sul selettore del menu .dropdown

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

15
Per correggere il clic deliberato, ho appena rimosso l' data-toggle="dropdown"attributo, che sembrava funzionare.
Anthony Briggs,

5
Soluzione (2) per i pulsanti della pillola di navigazione:.nav-pills .dropdown-menu { margin-top: 0px; }
Loren,

1
Per risolvere il problema ho notato sopra li.dropdown: hover> ul.dropdown-menu
Archimedes Trajano

12
la rimozione degli attributi "class" e "data-toggle" dai collegamenti di navigazione lo fa smettere di funzionare bene su dispositivi mobili e tablet :(
Mosijava,

1
Se hai rimosso l'attributo data-toggle = "dropdown", non sarai in grado di espandere il menu a discesa usando la tastiera. Quindi non sarà conforme a 508. Come è possibile disabilitare il clic ma mantenere la funzionalità della tastiera?
duyn9uyen,

130

Ho usato un po 'di 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();
});

13
Come questo. Sto usando JQuery comunque con il materiale Bootstrap e consente ancora la funzionalità predefinita di "clic" nei dispositivi touchscreen.
Duck in Custard,

Usato questo. Mi piace il fatto che permetta anche la funzionalità di clic, per i cellulari, ma per i desktop l'hover è perfetto.
Stuart,

1
L'ho usato ma l'ho esteso anche per essere utilizzabile per i menu a discesa che non sono in navigazione. Aggiungo il dropdown-hover della classe al div del gruppo btn e ho usato questo jQuery finder $ ('ul.nav li.dropdown, .dropdown-hover'). Hover (function () {. Grazie!
Brandon

Usato questo, bello e piccolo. La versione css non ha permesso di soggiorno sottomenu visualizzato e 200ms era troppo veloce, quindi ho cambiato $('ul.nav li.dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut().hover(function() { $(this).stop(true, true); }); });: quando il sottomenu è hover fermata fadeOut
Damien

questo non sembra funzionare con jqLite incluso in anguraljs
nuander

70

Ci sono molte ottime soluzioni qui. Ma ho pensato che avrei continuato e messo il mio qui come un'altra alternativa. È solo un semplice frammento di jQuery che lo fa come farebbe bootstrap se supportasse il passaggio del mouse per i menu a discesa anziché semplicemente fare clic. L'ho provato solo con la versione 3, quindi non so se funzionerebbe con la versione 2. Salvalo come snippet nel tuo editor e fallo alla pressione di una chiave.

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

Fondamentalmente, sta solo dicendo che quando passi con il mouse sulla classe a discesa, aggiungerà la classe aperta ad essa. Quindi funziona. Quando si interrompe il passaggio del mouse sul Li principale con la classe a discesa o il figlio ul / li, rimuove la classe aperta. Ovviamente, questa è solo una delle tante soluzioni e puoi aggiungerla per farlo funzionare solo su istanze specifiche di .dropdown. Oppure aggiungi una transizione a padre o figlio.


2
Ottima soluzione! Ho anche rimosso l'attributo data-toggle = "dropdown" dal link per rendere cliccabile il link superiore.
Sergey,

Questo è un buon consiglio Sergey. Mi assicuro sempre che il collegamento superiore non vada da nessuna parte in modo che funzioni anche su tablet e telefoni.
stereoscienza,

1
@Sergey Non consiglierei di farlo. Si romperà la funzionalità per gli utenti mobili. Non possono utilizzare la funzione hover per aprire un menu e devono essere in grado di fare clic su di esso.
Paul

2
È incredibilmente breve e facile pur essendo retrocompatibile con i touchscreen. Dovrebbe essere votato molto di più.
Max

Questo sembra davvero buono. Qualche idea su come aggiungere un po 'di animazione usando le transizioni CSS?
Fred Rocha,

70

Personalizza semplicemente il tuo stile CSS in tre righe di codice

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

22

Se hai un elemento con una dropdownclasse come questa (ad esempio):

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

Quindi puoi avere il menu a discesa da discesa automaticamente al passaggio del mouse, anziché fare clic sul suo titolo, usando questo frammento di codice 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>

Ecco una demo

Questa risposta si basava sulla risposta di @Michael , ho apportato alcune modifiche e aggiunto alcune aggiunte per far funzionare correttamente il menu a discesa


Perfetto. Molte grazie.
antikbd il

20

[Aggiornamento] Il plugin è su GitHub e sto lavorando su alcuni miglioramenti (come l'uso solo con attributi di dati (non è necessario JS). Ho lasciato il codice in basso, ma non è lo stesso di quello su GitHub.

Mi è piaciuta la versione puramente CSS, ma è bello avere un ritardo prima che si chiuda, poiché di solito è un'esperienza utente migliore (cioè non punita per una scivolata del mouse che va 1 px al di fuori del menu a discesa, ecc.), E come menzionato nei commenti , c'è quel 1px di margine che devi affrontare o a volte il nav si chiude inaspettatamente quando stai passando al menu a discesa dal pulsante originale, ecc.

Ho creato un piccolo plugin veloce che ho usato su un paio di siti e ha funzionato bene. Ogni elemento di navigazione viene gestito in modo indipendente, quindi ha i propri timer di ritardo, ecc.

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

Il delayparametro è piuttosto autoesplicativo e ilinstantlyCloseOthers chiuderà immediatamente tutti gli altri menu a discesa che sono aperti quando si passa sopra uno nuovo.

Non puro CSS, ma si spera che possa aiutare qualcun altro a quest'ora tarda (cioè questo è un vecchio thread).

Se vuoi, puoi vedere i diversi processi che ho attraversato (in una discussione #concrete5sull'IRC) per farlo funzionare attraverso i diversi passaggi di questa sintesi: https://gist.github.com/3876924

L'approccio del pattern plug-in è molto più pulito per supportare singoli timer, ecc.

Vedi il post sul blog per ulteriori informazioni.


17

Questo ha funzionato per me:

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

1
Con il cellulare però - è strano.
Radmation

Il margine tra menu e menu a discesa lo rende inutile.
antikbd il

15

Questo è integrato in Bootstrap 3. Basta aggiungere questo al tuo CSS:

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

10

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

3
Ho modificato il codice in jQuery('ul.nav li.dropdown').hover(function() { jQuery(this).closest('.dropdown-menu').stop(true, true).show(); jQuery(this).addClass('open'); }, function() { jQuery(this).closest('.dropdown-menu').stop(true, true).hide(); jQuery(this).removeClass('open'); });modo che il sottomenu non venga visualizzato al passaggio del mouse.
Farjam,

Questo codice non funzionerà più con le ultime versioni.
Paul

9

Puoi utilizzare il $().dropdown('toggle')metodo predefinito per attivare il menu a discesa al passaggio del mouse:

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

9

Voglio solo aggiungere che se hai più menu a discesa (come faccio io) dovresti scrivere:

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

E funzionerà correttamente.


Il mio menu .dropdown aveva margin: 2px 0 0;significato un mouse lento. L'ingresso dall'alto nascondeva il menu prematuramente. ul.dropdown-menu{ margin-top: 0; }
Alastair,

8

Secondo me il modo migliore è così:

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

Markup di esempio:

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

5
Questo è il lavoro di Cameron Spear, pensavo che gli avrei dato lo shoutout: cameronspear.com/blog/bootstrap-dropdown-on-hover-plugin
kelpie

8

Il modo migliore per farlo è semplicemente innescare l'evento click di Bootstrap con un passaggio del mouse. In questo modo, dovrebbe comunque rimanere compatibile con i dispositivi touch.

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

Risultato indesiderato: mouse, clic e mouseout lasceranno il menu aperto. Questo non è quello che voglio ...
Wietse il

Usando questo, Esegue la funzione bootstrap per aprire il menu a discesa, Quella funzione fa molte altre cose, come aria-
extended

7

L'ho gestito come segue:

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

Spero che questo aiuti qualcuno ...


5

Aggiunto anche margin-top: 0 per ripristinare il margine cst del bootstrap per il menu .dropdown in modo che l'elenco dei menu non scompaia quando l'utente passa lentamente dal menu a discesa all'elenco dei menu.

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

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

2
questa è la risposta corretta, bootstrap è pronto per il passaggio del mouse sul menu a discesa, se il mouse non esce dal menu a discesa. La rimozione del margine superiore consente di passare dal collegamento al menu senza interruzioni e quindi senza la chiusura automatica del menu. E questa soluzione consente di mantenere il comportamento corretto per i dispositivi touch
Nicolas Janel,

5

Questa è probabilmente un'idea stupida, ma per rimuovere semplicemente la freccia rivolta verso il basso, puoi eliminare

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

Questo non fa nulla per quello che punta, anche se ...


5

Ho pubblicato un plug-in adeguato per la funzionalità di passaggio del mouse a discesa Bootstrap 3, in cui puoi persino definire cosa succede quando fai clic suldropdown-toggle sull'elemento (il clic può essere disabilitato):

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


Perché l'ho fatto quando ci sono già molte soluzioni?

Ho avuto problemi con tutte le soluzioni precedentemente esistenti. Quelli CSS semplici non usano la .openclasse su .dropdown, quindi non ci sarà feedback sull'elemento toggle del menu a discesa quando il menu a discesa è visibile.

I j stanno interferendo con il clic su .dropdown-toggle, quindi il menu a discesa viene visualizzato al passaggio del mouse, quindi lo nasconde quando si fa clic su un menu a discesa aperto e lo spostamento del mouse attiverà il menu a discesa per comparire di nuovo. Alcune delle soluzioni js stanno rompendo la compatibilità iOS, alcuni plugin non funzionano sui moderni browser desktop che supportano gli eventi touch.

Ecco perché ho creato il plug-in Dropst Hover Bootstrap che previene tutti questi problemi utilizzando solo l'API javascript standard Bootstrap, senza alcun hack . Anche gli attributi Aria funzionano bene con questo plugin.


Qual è la tua opinione su github.com/vadikom/smartmenus ? Non riesco a decidere, entrambe le biblioteche sembrano essere davvero buone.
Csaba Toth,

2
Smartmenus sembra davvero buono, potrebbe essere migliore per i menu. Il mio plugin è solo una piccola aggiunta ai menu a discesa del bootstrap, non fa altro che aprire un menu a discesa al passaggio del mouse, mentre lo smartmenu supporta anche i sottomenu e fa altre cose fantasiose.
István Ujj-Mészáros,

1
Grazie. Vedo che il codice di smartmenu è molto esteso e ci sono anche molti CSS. Finora sono andato con bootstrap-dropdown-hover, perché sembra fare il lavoro e più compatto. Sto costruendo un sito di atterraggio con barra di navigazione sul lato sinistro.
Csaba Toth,

4

Utilizzare questo codice per aprire il sottomenu al passaggio del mouse (solo desktop):

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

E se vuoi che il menu di primo livello sia cliccabile, anche su dispositivo mobile aggiungi questo:

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

Il sottomenu (menu a discesa) verrà aperto con il passaggio del mouse sul desktop e con clic / tocco su cellulare e tablet. Una volta aperto il sottomenu, un secondo clic consente di aprire il collegamento. Grazie a if ($(window).width() > 767), il sottomenu occuperà la larghezza dello schermo intero su dispositivo mobile.


Vorrei usare il tuo codice, ma ho problemi a farlo funzionare correttamente. Innanzitutto, come rimuovere l'hover () per dispositivi mobili e utilizzarlo solo per desktop? Quando utilizzo il tuo codice e ridimensiono la finestra sul cellulare, ottengo sia la funzionalità hover () che click (). Ma ancora più strano ... è che questo comportamento si fermerà Quando aggiorno il browser, ah! Potresti mostrarmi come risolvere questo? Ho bisogno di sottomenu desktop da mostrare su hover () e fare clic su () per mostrare sottomenu su dispositivo mobile Senza dover aggiornare il browser anche quando si ridimensiona la finestra per funzionare correttamente. Spero che sia chiaro
Chris22,

ok, questo ha senso e cercherò di eseguire la tua soluzione nel modo che consigli. Grazie!
Chris22,

Usa questo metodo migliore: @falter
Farhad Sakhaei,


3

Questo nasconderà quelli in alto

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

3

Ciò dovrebbe nascondere i menu a discesa e i loro punti di inserimento se sono più piccoli di un tablet.

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

Perché vorresti nasconderlo? Ora gli utenti mobili non hanno modo di accedere ai collegamenti presenti nel sottomenu. È meglio disattivare l'effetto hover su un dispositivo mobile e mantenere intatto il menu a discesa. In questo modo possono aprirlo facendo clic su di esso.
Paul,

3

La soluzione jQuery è buona, ma dovrà occuparsi degli eventi al clic (per dispositivi mobili o tablet) poiché l'hover non funzionerà correttamente ... Potrebbe forse fare qualche rilevamento di ridimensionamento della finestra?

La risposta di Andres Ilich sembra funzionare bene, ma dovrebbe essere racchiusa in una query multimediale:

@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

La soluzione molto semplice per la versione 2, solo CSS. Mantiene la stessa funzionalità amichevole per dispositivi mobili e tablet.

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

Questo non funziona alla grande per alcuni temi in cui c'è un divario tra la voce di menu e il menu a discesa. Il menu scompare quando il mouse si sposta in questo spazio.
ndbroadbent

2

Sovrascrivi bootstrap.js con questo 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

Ecco la mia tecnica che aggiunge un leggero ritardo prima che il menu venga chiuso dopo aver smesso di passare con il mouse sul menu o sul pulsante di attivazione / disattivazione. Il <button>che normalmente cliccare per visualizzare il menu di navigazione è #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

Per migliorare la risposta di Sudharshan , lo avvolgo in una query multimediale per impedire il passaggio del mouse quando la larghezza del display XS ...

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

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

Inoltre, non è richiesto il punto di inserimento nel markup, ma solo la classe a discesa per li .


2

Questo funziona con WordPress Bootstrap:

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

2

Quindi hai questo codice:

<a class="dropdown-toggle" data-toggle="dropdown">Show menu</a>

<ul class="dropdown-menu" role="menu">
    <li>Link 1</li>
    <li>Link 2</li> 
    <li>Link 3</li>                                             
</ul>

Normalmente funziona su un evento click e vuoi che funzioni su un evento hover. Questo è molto semplice, basta usare questo codice 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();
        })
    })
})

Funziona molto bene ed ecco la spiegazione: abbiamo un pulsante e un menu. Quando si passa il mouse sul pulsante, viene visualizzato il menu e quando si passa il mouse sul pulsante, il menu viene nascosto dopo 100 ms. Se ti chiedi perché lo uso, è perché hai bisogno di tempo per trascinare il cursore dal pulsante sul menu. Quando si è nel menu, l'ora viene ripristinata e si può rimanere lì tutte le volte che si desidera. Quando esci dal menu, nasconderemo il menu all'istante senza alcun timeout.

Ho usato questo codice in molti progetti, se riscontri problemi nell'usarlo, sentiti libero di farmi domande.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.