Menu a discesa multilivello di Twitter Bootstrap


89

È possibile avere un menu a discesa multilivello utilizzando gli elementi di twitter bootstrap 2? La versione originale non ha questa caratteristica.


effettivamente cercato un'implementazione ma non sono stato fortunato.
Hellnar

Forse hai bisogno di un menu di pesce ventosa? htmldog.com/articles/suckerfish/dropdowns
Elaine Marley

1
dai un'occhiata anche a questo: github.com/twitter/bootstrap/issues/424
Paolo

Risposte:


113

Risposta aggiornata

* Risposta aggiornata che supporta il foglio di stile della versione bootstrap v2.1.1 **.

** Ma fai attenzione perché questa soluzione è stata rimossa dalla v3

Volevo solo sottolineare che questa soluzione non è più necessaria poiché l'ultimo bootstrap ora supporta menu a discesa multilivello per impostazione predefinita. Puoi ancora usarlo se sei su versioni precedenti ma per coloro che hanno aggiornato all'ultima (v2.1.1 al momento della scrittura) non è più necessario. Ecco un violino con il menu a discesa multi-livello predefinito aggiornato direttamente dalla documentazione:

http://jsfiddle.net/2Smgv/2858/


Risposta originale

Ci sono stati alcuni problemi sollevati sul supporto dei sottomenu su GitHub e di solito sono chiusi dagli sviluppatori di bootstrap, come questo , quindi penso che sia lasciato agli sviluppatori che usano il bootstrap per risolvere qualcosa. Ecco una demo che ho messo insieme che ti mostra come puoi hackerare un sottomenu funzionante.

Codice pertinente

CSS

.dropdown-menu .sub-menu {
    left: 100%;
    position: absolute;
    top: 0;
    visibility: hidden;
    margin-top: -1px;
}

.dropdown-menu li:hover .sub-menu {
    visibility: visible;
    display: block;
}

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

Ho creato la mia .sub-menuclasse da applicare ai menu a discesa a 2 livelli, in questo modo possiamo posizionarli accanto alle nostre voci di menu. Modificata anche la freccia per visualizzarla a sinistra del gruppo di sottomenu.

Demo


2
A partire da Bootstrap 2.0.4, devi anche avere la dichiarazione "display: block;" nel selettore ".dropdown-menu li: hover .sub-menu".
Omar

Ho provato ad implementarlo, il primo sottomenu funziona bene. Ma se aggiungo un altro sottomenu nello stesso menu, le cose vanno storte. Per qualche motivo apre il primo sottomenu invece del secondo. Qualsiasi idea o indizio sarebbe il benvenuto. Già grazie :)
Arjan

Hermes - Vedi la mia risposta su come risolvere il problema del sottomenu.
Sean Lynch

1
@Kannika rendere mobile questa correzione richiederebbe un markup extra e probabilmente anche un po 'di javascript. Suggerisco solo di visualizzare il contenuto a discesa di secondo livello invece di nasconderlo sui dispositivi mobili per mantenere le cose pulite. Proverò a lavorare su una soluzione più tardi durante la giornata. Tuttavia, non ho testato la soluzione bootstrap predefinita, quindi semmai puoi sempre seguirla.
Andres Ilich

5
La versione aggiornata funziona solo con Bootstrap 2.3.2, è stata rimossa in Bootstrap 3.0
seantomburke

34

[Twitter Bootstrap v3]

Per creare un menu a discesa di livello n (compatibile con il dispositivo touch) in Twitter Bootstrap v3,

CSS:

.dropdown-menu>li /* To prevent selection of text */
{   position:relative;
    -webkit-user-select: none; /* Chrome/Safari */        
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+ */
    /* Rules below not implemented in browsers yet */
    -o-user-select: none;
    user-select: none;
    cursor:pointer;
}
.dropdown-menu .sub-menu 
{
    left: 100%;
    position: absolute;
    top: 0;
    display:none;
    margin-top: -1px;
    border-top-left-radius:0;
    border-bottom-left-radius:0;
    border-left-color:#fff;
    box-shadow:none;
}
.right-caret:after,.left-caret:after
 {  content:"";
    border-bottom: 5px solid transparent;
    border-top: 5px solid transparent;
    display: inline-block;
    height: 0;
    vertical-align: middle;
    width: 0;
    margin-left:5px;
}
.right-caret:after
{   border-left: 5px solid #ffaf46;
}
.left-caret:after
{   border-right: 5px solid #ffaf46;
}

JQuery:

$(function(){
    $(".dropdown-menu > li > a.trigger").on("click",function(e){
        var current=$(this).next();
        var grandparent=$(this).parent().parent();
        if($(this).hasClass('left-caret')||$(this).hasClass('right-caret'))
            $(this).toggleClass('right-caret left-caret');
        grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');
        grandparent.find(".sub-menu:visible").not(current).hide();
        current.toggle();
        e.stopPropagation();
    });
    $(".dropdown-menu > li > a:not(.trigger)").on("click",function(){
        var root=$(this).closest('.dropdown');
        root.find('.left-caret').toggleClass('right-caret left-caret');
        root.find('.sub-menu:visible').hide();
    });
});

HTML:

<div class="dropdown" style="position:relative">
    <a href="#" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">Click Here <span class="caret"></span></a>
    <ul class="dropdown-menu">
        <li>
            <a class="trigger right-caret">Level 1</a>
            <ul class="dropdown-menu sub-menu">
                <li><a href="#">Level 2</a></li>
                <li>
                    <a class="trigger right-caret">Level 2</a>
                    <ul class="dropdown-menu sub-menu">
                        <li><a href="#">Level 3</a></li>
                        <li><a href="#">Level 3</a></li>
                        <li>
                            <a class="trigger right-caret">Level 3</a>
                            <ul class="dropdown-menu sub-menu">
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li><a href="#">Level 2</a></li>
            </ul>
        </li>
        <li><a href="#">Level 1</a></li>
        <li><a href="#">Level 1</a></li>
    </ul>
</div>

Sfortunatamente questo non mostra il menu quando viene visualizzato il pulsante "compresso" del menu. In Chrome e in FF.
Ben Power

@ BenPower Puoi per favore fornire una demo jsfiddle di esso, in modo che io possa esaminarlo perché la demo jsfiddle che ho dato funziona bene. Inoltre quali versioni di Bootstrap, JQuery e browser Web stai utilizzando?
Chirayu Chiripal

Funziona per Bootstrap v3.0. Amico ... Potresti renderlo di supporto per Bootstrap v2.3.2?
Niks Jain

1
Ho aggiunto trigger.off('click');prima di impostare i listener in modo da evitare il "doppio ascolto" di un evento nel caso in cui l'inizializzazione javascript venga attivata più di una volta.
FranBran

1
L'inversione del cursore ha aggiunto diverse righe di codice e non è necessario.
Ruben

23

Questo esempio è tratto da http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3

Funziona per me in Bootstrap v3.1.1.

HTML

<div class="container">
<div class="row">
    <h2>Multi level dropdown menu in Bootstrap 3</h2>
    <hr>
    <div class="dropdown">
        <a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" data-target="#" href="/page.html">
            Dropdown <span class="caret"></span>
        </a>
        <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
          <li><a href="#">Some action</a></li>
          <li><a href="#">Some other action</a></li>
          <li class="divider"></li>
          <li class="dropdown-submenu">
            <a tabindex="-1" href="#">Hover me for more options</a>
            <ul class="dropdown-menu">
              <li><a tabindex="-1" href="#">Second level</a></li>
              <li class="dropdown-submenu">
                <a href="#">Even More..</a>
                <ul class="dropdown-menu">
                    <li><a href="#">3rd level</a></li>
                    <li><a href="#">3rd level</a></li>
                </ul>
              </li>
              <li><a href="#">Second level</a></li>
              <li><a href="#">Second level</a></li>
            </ul>
          </li>
        </ul>
    </div>
</div>

CSS

.dropdown-submenu {
position: relative;
}

.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px;
border-radius: 0 6px 6px 6px;
}

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

.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #ccc;
margin-top: 5px;
margin-right: -10px;
}

.dropdown-submenu:hover>a:after {
border-left-color: #fff;
}

.dropdown-submenu.pull-left {
float: none;
}

.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}

Grazie ! la versione 3.0 non supporta più la risposta convalidata
Asenar

13

Sono stato in grado di correggere il blocco del sottomenu sempre nella parte superiore del menu principale dalla risposta di Andres con la seguente aggiunta:

.dropdown-menu li {
    position: relative;
}

Aggiungo anche un'icona "icon-chevron-right" sugli elementi che contengono sottomenu di menu e cambio l'icona da nera a bianca al passaggio del mouse (per complimentarmi con il testo che cambia in bianco e avere un aspetto migliore con lo sfondo blu selezionato).

Ecco la modifica completa di less / css (sostituire quanto sopra con questo):

.dropdown-menu li {
    position: relative;

    [class^="icon-"] {
        float: right;
    }

    &:hover {
        // Switch to white icons on hover
        [class^="icon-"] {
            background-image: url("../img/glyphicons-halflings-white.png");
        }
    }
}

4

Ho appena aggiunto class="span2"agli <li>elementi del menu a discesa e ha funzionato.


3

Poiché Bootstrap 3 ha rimosso la parte del sottomenu e dobbiamo adattare noi stessi lo stile, penso che sia meglio andare con SmartMenu Bootstrap: https://vadikom.github.io/smartmenus/src/demo/bootstrap-navbar.html#

Ciò ci farebbe risparmiare tempo su dispositivi mobili reattivi e di stile.

Anche questo plugin è molto promettente.


Qual è la tua opinione su github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover ? Non posso decidere.
Csaba Toth

1
@CsabaToth, anche questo era nella mia considerazione, se vuoi avere solo l'API javascript bootstrap, puoi usare questo, abbastanza leggero da aggiungere e puoi avere familiarità con l'abilità di bootstrap generale se hai bisogno di personalizzazione.
Osify

Finalmente ne userò uno in un progetto e l'altro in un sito complementare. Ogni soluzione si adatta meglio a una di esse
Csaba Toth,
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.