Zamknij responsywne menu Bootstrap „po kliknięciu”


86

Po kliknięciu „PRODUKTY” przesuwam w górę biały div (jak widać na załączonym). W responsywnym (mobilnym i tablecie) chciałbym automatycznie zamknąć responsywny pasek nawigacyjny i pokazywać tylko biały pasek.

Próbowałem:

$('.btn-navbar').click();  

również próbował:

$('.nav-collapse').toggle();

I to działa. Jednak w rozmiarze pulpitu jest również nazywany i robi coś dziwnego w menu, w którym kurczy się na sekundę.

Jakieś pomysły?

wprowadź opis obrazu tutaj


Czy możesz opublikować trochę HTML? Czy używasz Bootstrap do funkcji ukrywania? A może próbujesz wdrożyć coś własnego?
Kris Hollenbeck

Myślę, że po prostu próbuję zrobić coś prostego. Chcę tylko zamknąć pasek nawigacyjny, kiedy kliknę „PRODUKTY”
user1040259

Jeśli nie chcesz samodzielnie porównywać wszystkich tych rozwiązań, edytuj numer 1 z tej odpowiedzi, co powinieneś zrobić.
krakanie

Polecam przewinąć trochę w dół i spojrzeć na odpowiedź @LukeTillman. Działa doskonale i bez jQuery. :)
das Keks

Odpowiedzi:


102

Mam to do pracy z animacją!

Menu w html:

<div id="nav-main" class="nav-collapse collapse">
     <ul class="nav">
         <li>
             <a href='#somewhere'>Somewhere</a>
         </li>
     </ul>
 </div>

Zdarzenie kliknięcia powiązania na wszystkich elementach w nawigacji do menu zwijania (wtyczka zwijania Bootstrap):

 $(function(){ 
     var navMain = $("#nav-main");
     navMain.on("click", "a", null, function () {
         navMain.collapse('hide');
     });
 });

EDYCJA Aby uczynić go bardziej ogólnym, możemy użyć następującego fragmentu kodu

 $(function(){ 
     var navMain = $(".navbar-collapse"); // avoid dependency on #id
     // "a:not([data-toggle])" - to avoid issues caused
     // when you have dropdown inside navbar
     navMain.on("click", "a:not([data-toggle])", null, function () {
         navMain.collapse('hide');
     });
 });

3
Jeśli nie wszystkie aelementy: wystarczy zadzwonić$("#nav-main").collapse('hide');
Ankit Jain

@mollwe Czy masz rozwiązanie, gdy ma menu rozwijane? Zrobiłem jsfiddle, aby spróbować, ale nawet menu się nie otwiera. jsfiddle.net/Y3H92
clankill3r

@ clankill3r wydaje mi się, że brakuje odniesienia do pliku bootstrap.js i dlatego menu nie będzie działać. Zaktualizowałem twój jsfiddle: jsfiddle.net/Y3H92/1
mollwe

@mollwe z twoimi skrzypcami menu w ogóle się nie zamknie.
clankill3r

1
Przepraszamy za spóźnioną odpowiedź @ clankill3r! Ale lepiej późno niż wcale. jsfiddle.net/mollwe/Y3H92/5
mollwe

136

Nie musisz dodawać żadnego dodatkowego javascript do tego, co jest już zawarte w opcji zwijania bootstraps. Zamiast tego po prostu umieść selektory przełączania danych i celów danych na elementach listy menu, tak jak robisz to z przyciskiem przełączania paska nawigacyjnego. Tak więc w przypadku pozycji menu Produkty wyglądałoby to tak

<li><a href="#Products" data-toggle="collapse" data-target=".navbar-collapse">Products</a></li>

Następnie należałoby powtórzyć selektory przełączania danych i celu danych dla każdego elementu menu

EDYTOWAĆ!!! Aby naprawić problemy z przepełnieniem i migotaniem tej poprawki, dodaję więcej kodu, który to naprawi i nadal nie będzie mieć żadnego dodatkowego javascript. Oto nowy kod:

<li><a href="#products" class="hidden-xs">Products</a></li>
<li><a href="#products" class="visible-xs" data-toggle="collapse" data-target=".navbar-collapse">Products</a></li>

Tutaj jest w pracy http://jsfiddle.net/jaketaylor/84mqazgq/

Spowoduje to, że przełączniki i selektory docelowe będą dostosowane do rozmiaru ekranu i wyeliminują usterki w większym menu. Jeśli ktoś nadal ma problemy z usterkami, daj mi znać, a znajdę rozwiązanie. Dzięki

EDYCJA : W bootstrap v4.1.3 nie mogłem używać widocznych / ukrytych klas. Zamiast hidden-xsużywać d-none d-sm-blocki zamiast visible-xsużywać d-block d-sm-none.


14
co powoduje migotanie i dziwne rzeczy, gdy nawigacja nie jest wyświetlana jako "responsywne" menu.
Florian

5
To jest poprawna implementacja. Nie jest potrzebne niestandardowe jQuery.
larrylampco

Usunąłem mój głos przeciw tej odpowiedzi i mój poprzedni komentarz (również dlatego, że wideo już nie działało). ponieważ mój komentarz na temat migotania jest nadal ważny dla oryginalnej odpowiedzi, dostałem kilka głosów za, a twoja „edycja” jest wyraźnie zaznaczona, nie widzę powodu, aby go usunąć i przepisać historię. był on ważny w tamtym czasie i odpowiednio zareagowałeś. osoby czytające Twoją odpowiedź zobaczą „edytuj” i będą wiedzieć, że ją poprawiłeś ...
Florian

Wolisz powielać wszystkie swoje linki tylko po to, aby uniknąć jednej linii doskonale udokumentowanego javascript? getbootstrap.com/javascript/#collapse-methods .
Sander Garretsen,

1
Zamiast dodawać atrybuty data-togglei data-targetdo każdego elementu li, możesz zamiast tego dodać go do elementu nadrzędnego ullub divznaczników.
Jeremy Quick

40

Myślę, że zajmujesz się inżynierią ...

    $('.navbar-collapse ul li a').click(function(){ 
            $('.navbar-toggle:visible').click();
    });

EDYCJA: Aby zadbać o podmenu, upewnij się, że ich kotwica przełączania ma na sobie klasę przełączania rozwijanego.

    $(function () { 
            $('.navbar-collapse ul li a:not(.dropdown-toggle)').click(function () { 
                    $('.navbar-toggle:visible').click(); 
            }); 
    });

EDYCJA 2: Dodaj obsługę dotyku telefonu.

    $(function () {
            $('.navbar-collapse ul li a:not(.dropdown-toggle)').bind('click touchstart', function () {
                    $('.navbar-toggle:visible').click();
            });
    });

3
Powinna być zaakceptowana odpowiedź. Pozostałe przeprojektowane i migoczą na niereaktywnym wyświetlaczu.
rybo111

3
To mogłaby być akceptowana odpowiedź, ale nie bierze pod uwagę podmenu i faktycznie je łamie. Niektóre z innych „nadmiernie zaprojektowanych” rozwiązań brały to pod uwagę pomimo swoich wad. Zadba o to następujący dodatek: $ (function () {$ ('. Navbar-collapse ul li a: not (.dropdown-toggle)'). Click (function () {$ ('. Navbar-toggle: widoczny '). click ();});});
Ed Bishop

świetnie, dzięki za EDYCJĘ!
Hontoni

1
Myślę, że touchstart to trochę za dużo, kliknięcie działa dobrze. jak reaguje na przesuwanie, gdy „zaczynasz” od przycisku?
Hontoni

37

Bardzo podobał mi się pomysł Jake'a Taylora, aby zrobić to bez dodatkowego JavaScript i wykorzystać przełącznik zwijania Bootstrapa. Zauważyłem, że możesz rozwiązać problem „migotania” występujący, gdy menu nie jest zwinięte data-target, nieznacznie modyfikując selektor, aby uwzględnić inklasę. Więc wygląda to tak:

<li><a href="#Products" data-toggle="collapse" data-target=".navbar-collapse.in">Products</a></li>

Nie testowałem tego z zagnieżdżonymi listami rozwijanymi / menu, więc YMMV.


3
Dla mnie też była to najlepsza realizacja.
huijing

Z jakiegoś powodu mój ScrollSpy zrywa z tą metodą, ale działa dobrze z metodą Jake'a Taylora.
Inkling

Jak dotąd najlepsza i najprostsza odpowiedź.
Diaa,

Przez jakiś czas próbowałem sprawić, by zawalenie się nie migotało, ale jest to zdecydowanie najprostsze i najbardziej eleganckie rozwiązanie. Dziękuję Ci!
McVenco

9

żeby być kompletnym, w Bootstrap 4.0.0-beta użycie .show działało dla mnie ...

<li>
  <a href="#Products" data-toggle="collapse" data-target=".navbar-collapse.show">Products</a>
</li>

Najlepsza odpowiedź dla mnie, dziękuję.
MoxxiManagarm

5

Zakładam, że masz taką linię definiującą obszar nawigacyjny, opartą na przykładach Bootstrap i wszystkim

<div class="nav-collapse collapse" >

Po prostu dodaj właściwości jako takie, jak na przycisku MENU

<div class="nav-collapse collapse" data-toggle="collapse"  data-target=".nav-collapse">

Dodałem do <body> też, działało. Nie mogę powiedzieć, że sprofilowałem to czy coś, ale wydaje mi się to przyjemnością ... dopóki nie klikniesz losowego miejsca w interfejsie użytkownika, aby otworzyć menu, więc nie tak dobrze.

DK


Właściwe rozwiązanie oparte na wbudowanej funkcjonalności Bootstrap; bez dodatkowego jQuery lub javascript. I najprostsze rozwiązanie ze wszystkich. To powinna być akceptowana odpowiedź.
Sergi Papaseit

4

To działa, ale nie ożywia.

$('.btn-navbar').addClass('collapsed');
$('.nav-collapse').removeClass('in').css('height', '0');

8
To trochę zaskakujące, że nie ma do tego opcji konfiguracji, ponieważ bliskość kliknięcia byłaby lepszym ustawieniem domyślnym.
bchesley

3

W HTML dodałem klasę nav-link do tagu a każdego linku nawigacyjnego.

$('.nav-link').click(
    function () {
        $('.navbar-collapse').removeClass('in');
    }
);

3

to rozwiązanie ma dobrą pracę, na komputerach stacjonarnych i urządzeniach mobilnych.

<div id="navbar" class="navbar-collapse collapse" data-toggle="collapse"  data-target=".navbar-collapse collapse">

zadziałało, gdy używam navbar-id jako celu danych: <div id = "navbar" class = "collapse navbar-collapse" data-toggle = "collapse" data-target = "# navbar">, ale daje brzydką animację w rozmiarze pulpitu
wutzebaer

Bardzo brzydkie, nie do przyjęcia!
świecznik

2

Aby przeliterować rozwiązanie user1040259, dodaj ten kod do swojego $ (document) .ready (function () {});

    $('.nav').click( function() {
        $('.btn-navbar').addClass('collapsed');
        $('.nav-collapse').removeClass('in').css('height', '0');
    });

Jak wspominają, to nie animuje ruchu ... ale zamyka pasek nawigacyjny przy wyborze przedmiotu


2

Dla tych, którzy używają AngularJS i Angular UI Router z tym, oto moje rozwiązanie (używając przełącznika mollwe). Gdzie „.navbar-main-collapse” to mój „cel danych”.

Utwórz dyrektywę:

module.directive('navbarMainCollapse', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'C',
        link: function (scope, element) {
            //watch for state/route change (Angular UI Router specific)
            $rootScope.$on('$stateChangeSuccess', function () {
                if (!element.hasClass('collapse')) {
                    element.collapse('hide');
                }
            });
        }
    };
}]);

Dyrektywa użytkowania:

<div class="collapse navbar-collapse navbar-main-collapse">
    <your menu>

Wygląda na to, że umieściłeś dyrektywę w atr klasy, czy to prawda?
Gringo Suave,

Wewnątrz funkcji łącza powinny działać następujące elementy. element.on ('click', function () {scope.vm.isCollapsed =! scope.vm.isCollapsed;});
JimmyBob

2

To powinno załatwić sprawę.

Wymaga bootstrap.js.

Przykład => http://getbootstrap.com/javascript/#collapse

    $('.nav li a').click(function() {
      $('#nav-main').collapse('hide');
    });

Działa to tak samo, jak dodanie atrybutów „data-toggle =" collapse "” i „href =" yournavigationID "” do tagów menu nawigacji.


Czy mógłbyś bardziej szczegółowo wyjaśnić odpowiedź?
Blunderfest

Czy to nie jest jQuery? Czy używanie zarówno jQuery, jak i Angular nie jest ogólnie złą praktyką?
AlxVallejo

1

Używam funkcji mollwe, chociaż dodałem 2 ulepszenia:

a) Unikaj zamykania listy rozwijanej, jeśli kliknięty link jest zwinięty (w tym inne linki)

b) Ukryj również listę rozwijaną, jeśli klikasz widoczną treść internetową.

jQuery.fn.exists = function() {
                  return this.length > 0;
              }

    $(function() {
                var navMain = $(".navbar-collapse");
                navMain.on("click", "a", null, function() {
                    if ($(this).attr("href") !== "#") {
                        navMain.collapse('hide');
                    }
                });

                $("#content").bind("click", function() {
                     if ($(".navbar-collapse.navbar-ex1-collapse.in").exists()) {
                        navMain.collapse('hide');
                    }
                });

            });

1

Nie jest to najnowszy wątek, ale szukałem rozwiązania tego samego problemu i znalazłem jeden (mieszankę kilku innych).

Podałem NavButton:

<type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> ...

identyfikator / identyfikator, taki jak:

 <button id="navcop" type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

Nie jest to najlepszy „pomysł” - ale: dla mnie działa! Teraz możesz sprawdzić widoczność swojego przycisku (za pomocą jQuery) na przykład:

 var target = $('#navcop');
   if(target.is(":visible")){
   $('#navcop').click();
   }

(UWAGA: to tylko fragment kodu! Użyłem zdarzenia „onclick” na moich łączach nawigacyjnych! (Rozpoczynanie procedury AJAX).

Rezultat jest następujący: jeśli przycisk jest „widoczny”, został „kliknięty” ... Więc: nie ma błędu, jeśli używasz „widoku pełnoekranowego” programu Bootstrap (szerokość ponad 940 pikseli).

Pozdrowienia Ralph

PS: Działa dobrze z IE9, IE10 i Firefox 25. Nie sprawdzałem innych - ale nie widzę problemu :-)


1

To zadziałało dla mnie. Zrobiłem tak, kiedy klikam przycisk menu, dodając lub usuwając klasę „w”, ponieważ dodając lub usuwając tę ​​klasę, przełącznik działa domyślnie. 'e.stopPropagation ()' polega na zatrzymaniu domyślnej animacji przez bootstrap (tak sądzę), możesz także użyć 'toggleClass' zamiast dodawania lub usuwania klasy.

$ ('# ChangeToggle'). On ('click', function (e) {

        if ($('.navbar-collapse').hasClass('in')) {
            $('.navbar-collapse').removeClass('in');
            e.stopPropagation();
        } else {
            $('.navbar-collapse').addClass('in');
            $('.navbar-collapse').collapse();
        }

    });

0

Możesz użyć

ul.nav {
    display: none;
}

Spowoduje to domyślne zamknięcie paska nawigacyjnego. Proszę, daj mi znać, że ktoś uzna to za przydatne


2
Problem w tym, że ukrywa to nawigację, gdy jest wyświetlana "normalnie", a nie w responsywnym menu.
Florian

0

Jeśli na przykład ikona z możliwością przełączania jest widoczna tylko dla bardzo małych urządzeń, możesz zrobić coś takiego:

$('[data-toggle="offcanvas"]').click(function () {
    $('#side-menu').toggleClass('hidden-xs');
});

Kliknięcie [data-toggle = "offcanvas"] doda plik .hidden-xs programu bootstrap do mojego # menu bocznego, które ukryje zawartość menu bocznego, ale stanie się ponownie widoczne, jeśli zwiększysz rozmiar okna.


0

jeśli menu html to

<div id="nav-main" class="nav-collapse collapse">
     <ul class="nav">
         <li>
             <a href='#somewhere'>Somewhere</a>
         </li>
     </ul>
</div>

on nav toggle Klasa „in” jest dodawana i usuwana z przełącznika. sprawdź, czy responsywne menu jest otwarte, a następnie wykonaj przełącznik zamykania.

$('.nav-collapse .nav a').on('click', function(){
    if ( $( '.nav-collapse' ).hasClass('in') ) {
        $('.navbar-toggle').click();
    }
});

0

Tuggle Nav Close, odpowiedź zgodna z przeglądarką IE, bez błędu konsoli. Jeśli używasz bootstrap, użyj tego

$('.nav li a').on('click', function () {
    if ($("#navbar").hasClass("in")) {
        $('.navbar-collapse.in').show();
    }
    else {
        $('.navbar-collapse.in').hide();
    }
})

-1
$('.navbar-toggle').trigger('click');

Nie rozumiem, dlaczego to nie jest dobra odpowiedź? za każdym razem, gdy klikniesz którykolwiek z linków menu w tym zdarzeniu kliknięcia, możesz przełączyć menu, co uważam za właściwy sposób, ponieważ nie zmieniam domyślnego zachowania menu otwierania lub zamykania.
Aqib

-1

Rozwiązanie Bootstrap 4 bez Javascript

Dodaj atrybuty data-toggle="collapse" data-target="#navbarSupportedContent.show" do div<div class="collapse navbar-collapse">

Upewnij się, że zapewniają prawidłowe idindata-target

<div className="collapse navbar-collapse" id="navbarSupportedContent" data-toggle="collapse" data-target="#navbarSupportedContent.show">

.show ma na celu uniknięcie migotania menu w dużych rozdzielczościach

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent" data-toggle="collapse" data-target="#navbarSupportedContent.show">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

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.