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

user1040259
źródło
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');
     });
 });
mollwe
źródło
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.

Jake Taylor
źródło
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();
            });
    });
Hontoni
źródło
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.

Luke Tillman
źródło
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>
vidriduch
źródło
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

Douglas „DK” Knudsen
źródło
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');
user1040259
źródło
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');
    }
);
Jason Swingen
źródło
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">
bp002
źródło
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

Karol A.
źródło
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>
Kyle
źródło
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.

Jussi Järviö
źródło
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');
                    }
                });

            });
Arco Voltaico
źródło
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 :-)

Ralph D.
źródło
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();
        }

    });
Goutami
źródło
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

Kris
źródło
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.

Kingsley Ijomah
źródło
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();
    }
});
Aamer Shahzad
źródło
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();
    }
})
Super Model
źródło
-1
$('.navbar-toggle').trigger('click');
Aqib
źródło
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>

kiranvj
źródło