Rozwijane menu Bootstrap z Hover


179

OK, więc to, czego potrzebuję, jest dość proste.

Skonfigurowałem pasek nawigacyjny z kilkoma rozwijanymi menu (za pomocą class="dropdown-toggle" data-toggle="dropdown") i działa dobrze.

Chodzi o to, że działa „ onClick”, a ja wolałbym, gdyby działało „ onHover”.

Czy jest jakiś wbudowany sposób to zrobić?


Zobacz moją nowo opublikowaną właściwą wtyczkę, która zapobiega problemom z poniższymi rozwiązaniami CSS i js: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Odpowiedzi:


338

Najłatwiejszym rozwiązaniem byłoby CSS. Dodaj coś takiego ...

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

Working Fiddle


3
O wiele lepsze niż długie „pełne” rozwiązania. Wystarczy dodać to, a domyślny menu „kliknięcie” działa po najechaniu myszą bez dodatkowych zmian.
IamFace

47
Spowoduje to konflikt z wbudowanym składanym menu mobilnym, więc powinieneś owinąć go punktem przerwania @media (min-width: 480px)
Billy Shih

7
Warto również zauważyć: jeśli masz menu rozwijane z relacjami rodzic-dziecko, na przykład w motywie wordpress, musisz usunąć data-toggleatrybut, aby element nadrzędny był klikalny ... Po prostu uważaj na uszkodzenia na ekranach urządzeń mobilnych.
Ken Prince

2
Czy jest jakiś prosty sposób, aby wyłączyć wyświetlanie po kliknięciu i zachować tylko zachowanie najechania myszą?
Micer

1
@Micer, właśnie opublikowałem wtyczkę, w której możesz wyłączyć zdarzenie kliknięcia. Wtyczka działa bez włamania CSS, używając tylko API javascript Bootstrap, więc jest kompatybilna ze wszystkimi urządzeniami: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

66

Najlepszym sposobem na to jest po prostu wywołanie zdarzenia kliknięcia bootstraps za pomocą najechania kursorem. W ten sposób powinien pozostać przyjazny dla urządzenia dotykowego

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

1
kończy się niepowodzeniem, jeśli masz więcej niż jeden poziom rozwijania
Connie DeCinko

1
Nie działa z łączem nadrzędnym
pio

czy istnieje sposób na usunięcie klasy Active po zamknięciu menu rozwijanego?
brainvision

Między elementem rozwijanym a menu jest przerwa w pikselach, która może powodować ukrywanie się menu, chyba że jesteś szybki
Matt

1
Korzystanie z wielu list rozwijanych wymaga „najbliższego” filtrowania.
err

57

Możesz użyć funkcji aktywowania jQuery.

Musisz tylko dodać klasę, opengdy mysz wchodzi i usunąć klasę, gdy mysz opuszcza menu rozwijane.

Oto mój kod:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});

10
O wiele lepiej niż przyjęta odpowiedź imho. Dzięki temu cała logika bootowania i styl pozostają nienaruszone. Chociaż radzę skorzystać z drugiego oddzwaniania i jawnie użyć removeClass i addClass, aby zapobiec dziwnym zachowaniom po kliknięciu przycisku (gdzie otworzy się po opuszczeniu przycisku i zamknie po wejściu).
Bastiaan Linders

3
Myślę też, że to najlepsza odpowiedź. Aby to działało z menu Bootstrap 4, musiałem użyć showzamiast open, a także dołączyć dropdown-menu: $('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(Przepraszam za formatowanie.)
Robin Zimmermann

Nie działa, jeśli masz dwa elementy menu rozwijanego. Po najechaniu kursorem na dowolny element menu rozwijanego zostaną wyświetlone oba podmenu
Juan Antonio Tubío

23

Łatwy sposób, przy użyciu jQuery, jest następujący:

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

Uwielbiam płynne przejście, jednak powoduje, że wszystkie poziomy menu rozwijają się zamiast tylko pierwszego poziomu. Nie chcę, aby pojawiały się menu drugiego poziomu, dopóki nie zatrzymam wskaźnika nad ich rodzicem.
Connie DeCinko,

1
Aby uzyskać tylko pierwszy poziom, dodaj .first() - $(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);...
JEdot

9

W przypadku CSS wariuje, gdy również go klikniesz. To jest kod, którego używam, nie zmienia też niczego w widoku mobilnym.

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

Piękność! Tx! Alternatywy CSS nie będą działać na Bootstrap 3 i nowszych wersjach.
Pedro Ferreira,



5

Więc masz ten kod:

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

Zwykle działa na zdarzenie kliknięcia i chcesz, aby działało na zdarzeniu najechania kursorem. Jest to bardzo proste, wystarczy użyć tego kodu 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();
        })
    })
})

Działa to bardzo dobrze i oto wyjaśnienie: mamy przycisk i menu. Po najechaniu myszką na przycisk wyświetlamy menu, a po najechaniu myszką na przycisk ukrywamy menu po 100 ms. Jeśli zastanawiasz się, dlaczego go używam, to dlatego, że potrzebujesz czasu, aby przeciągnąć kursor z przycisku nad menu. Po przejściu do menu czas jest resetowany i możesz tam pozostać tyle czasu, ile chcesz. Po wyjściu z menu natychmiast ukryjemy menu, bez żadnego limitu czasu.

Użyłem tego kodu w wielu projektach, jeśli napotkasz jakiś problem z jego użyciem, możesz zadawać mi pytania.


Ten kod ma wiele problemów z bootstrap v3. 1.) Jeśli jest więcej niż jedno menu rozwijane, wszystkie menu rozwijane są wyświetlane po najechaniu kursorem. 2.) Na małych ekranach najechanie kursorem pokazuje menu rozwijane w dziwny sposób.
KayakinKoder 17.07.17

4

To jest to, czego używam, aby zrobić to rozwijane po najechaniu kursorem za pomocą 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');
    });
});

Ładne, ale nie obsługuje podmenu.
Connie DeCinko,

3

Wypróbuj tę funkcję za pomocą funkcji aktywowania z animacjami zanikania i zanikania

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

Ta animacja nie działa na 3. głębokości, ale działa na 2. głębokości. Czy masz jakieś inne rozwiązanie dla 3. głębokości?
Jilani A

proszę dodać JSFiddle w celach informacyjnych
Rakesh Vadnal

2

Pomoże ci to stworzyć własną klasę aktywacji dla 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;
}

Marginesy są ustawione w celu uniknięcia niechcianego zamykania i są opcjonalne.

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>

Nie zapomnij usunąć atrybutu przycisku data-toggle = "menu rozwijane", jeśli chcesz usunąć kliknięcie po otwarciu, a to zadziała również, gdy dane wejściowe zostaną dołączone do menu rozwijanego.


2

To powoduje najechanie na pasek nawigacyjny tylko wtedy, gdy nie jesteś na urządzeniu mobilnym, ponieważ uważam, że najechanie na nawigację nie działa dobrze na urządzeniach mobilnych:

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

});

O wiele lepsze rozwiązanie znajdziesz tutaj: github.com/CWSpear/bootstrap-hover-dropdown .
solarbaypilot

2

Wypróbowuję inne rozwiązania, używam bootstrap 3, ale menu rozwijane zamyka się zbyt szybko, aby przejść nad nim

Przypuszczalnie dodałeś do li class = "dropdown", dodałem limit czasu

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

2

Zaktualizowano z odpowiednią wtyczką

Opublikowałem odpowiednią wtyczkę dla funkcji rozwijanego menu, w której możesz nawet zdefiniować, co dzieje się po kliknięciu dropdown-toggleelementu:

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


Dlaczego to zrobiłem, skoro jest już wiele rozwiązań?

Miałem problemy ze wszystkimi poprzednimi rozwiązaniami. Proste CSS nie używają tej .openklasy na .dropdown, więc nie będzie żadnych informacji zwrotnych na temat elementu rozwijanego, gdy menu rozwijane jest widoczne.

Js przeszkadzają w kliknięciu .dropdown-toggle, więc menu pojawia się po najechaniu myszką, a następnie ukrywa je po kliknięciu otwartego menu, a poruszenie myszą spowoduje, że menu pojawi się ponownie. Niektóre rozwiązania js hamują kompatybilność z iOS, niektóre wtyczki nie działają w nowoczesnych przeglądarkach komputerowych, które obsługują zdarzenia dotykowe.

Dlatego stworzyłem wtyczkę Bootstrap Dropdown Hover, która zapobiega wszystkim tym problemom, używając tylko standardowego interfejsu API javascript Bootstrap, bez żadnego włamania.


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

1

Wyzwalanie clickzdarzenia za hoverpomocą małego błędu. Jeśli mouse-ini wtedy a clicktworzy efekt odwrotnie. To openskiedy mouse-outi closekiedy mouse-in. Lepsze rozwiązanie:

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

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


0

Rozwiązanie, które proponuję, wykrywa, czy nie jest to urządzenie dotykowe i czy navbar-toggle(menu hamburgera) nie jest widoczne, i powoduje, że element menu nadrzędnego ujawnia podmenu po najechaniu myszką i podąża za linkiem po kliknięciu .

Ustawia także 0 na marginesie, ponieważ przerwa między paskiem nawigacyjnym a menu w niektórych przeglądarkach nie pozwala na najechanie na podelementy

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


0

Lista rozwijana Bootstrap Pracuj po najechaniu kursorem i pozostań blisko kliknięcia, dodając właściwość display: block; w css i usunięcie tych atrybutów data-toggle = "dropdown" role = "button" ze znacznika 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>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.