Zwinięte menu Bootstrap 3 nie zamyka się po kliknięciu

122

Mam mniej więcej standardową nawigację z bootstrap 3

<body data-spy="scroll" data-target=".navbar-collapse">
    <!-- ---------- Navigation ---------- -->
    <div class="navbar navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                </button>
                <a class="navbar-brand" href="index.html"> <img src="#"></a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li class="active"><a href="#home">Home</a></li>
                    <li><a href="#one">One</a></li>
                    <li><a href="#two">Two</a></li>
                    <li><a href="#three">Three</a></li>
                    <li><a href="#four">Four</a></li>
                </ul>
            </div>
        </div>
    </div>

Zwykle zapada się na mniejszych urządzeniach. Kliknięcie przycisku menu powoduje rozwinięcie menu, ale jeśli kliknę (lub dotknę w tym przypadku) łącze menu, menu pozostanie otwarte. Co mam zrobić, aby ponownie je zamknąć?

Paranoja
źródło
5
odpowiedź użytkownika 3669917 jest z pewnością najłatwiejszą i najprostszą odpowiedzią!
Thomas

Odpowiedzi:

48

Domyślnym ustawieniem Bootstrap jest pozostawienie otwartego menu po kliknięciu elementu menu. Możesz ręcznie zastąpić to zachowanie, wywołując .collapse('hide');element jQuery, który chcesz zwinąć.

VCNinc
źródło
8
To jest złe, bootstrap automatycznie przełącza klasę „collapse”. Nie potrzebujesz żadnego dodatkowego kodu jQuery. Jeśli masz takie zachowanie, oznacza to, że coś jest nie tak w twoim kodzie HTML (ze swojej strony dodałem dwukrotnie jquery i bootstrap, zobacz odpowiedź @raisercostin).
RomOne
@RomOne Ta odpowiedź jest poprawna. Bootstrap czy nie zamknąć menu po kliknięciu łącza są domyślnie. Druga odpowiedź ma zastosowanie tylko wtedy, gdy ludzie niepoprawnie dołączają dwukrotnie jQuery, co nie jest poprawną odpowiedzią na to pytanie.
Zim
136

Aby podzielić się tym z rozwiązań na GitHub, oto popularna odpowiedź:

https://github.com/twbs/bootstrap/issues/9013#issuecomment-39698247

$(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a') ) {
        $(this).collapse('hide');
    }
});

Jest to połączone z dokumentem, więc nie musisz tego robić w ready () (możesz dynamicznie dołączać linki do swojego menu i nadal będzie działać), a wywoływane jest tylko wtedy, gdy menu jest już rozwinięte. Niektórzy ludzie zgłaszali dziwne flashowanie w miejscu, w którym menu otwiera się, a następnie natychmiast zamyka innym kodem, który nie weryfikował, czy menu zawiera klasę „in”.

[UPDATE 2014-11-04] najwyraźniej podczas korzystania z podmenu powyższe może powodować problemy, więc powyższe zostało zmodyfikowane do:

$(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a:not(".dropdown-toggle")') ) {
        $(this).collapse('hide');
    }
});
Kevin Nelson
źródło
1
Działa bez zarzutu. Dzięki za udostępnienie!
Rodrigo Chiong
Czy możesz wyjaśnić '$ (this) .collapse (' hide ');' Proszę. nie rozumiem, skąd się bierze „upadek”
timebandit
@ImranNazir, przepraszam, że to jest po pytaniu, ale collapsejest to metoda zdefiniowana przez bootstrap i dołączona do obiektu jQuery ... prawdopodobnie ponownie używają tego do wielu celów (akordeon, pasek nawigacyjny itp.): Getbootstrap.com/javascript / # collapse-use
Kevin Nelson
Zaktualizowany kod działał dla mnie, odpowiedzi powyżej nie działały. Dzięki!
RandomUs1r
„[UPDATE 2014-11-04]” zadziałało. Jeśli chodzi o inne rozwiązanie, w którym zaleca się usunięcie zduplikowanych odniesień do bootstrap.js i jquery, które nie są konieczne, rozwiązanie. Znalazłem to rozwiązanie, które rozwiązuje problem przy mniejszym czasie debugowania i bardziej wyraźnym zachowaniu. Dziękuję Ci!. Mam nadzieję, że to ci pomogło, tak jak pomogło mi.
Nour Lababidi
122

Zmień to:

<li><a href="#one">One</a></li>

do tego:

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

Ta prosta zmiana zadziałała dla mnie.

Ref: https://github.com/twbs/bootstrap/issues/9013

FullStackDev
źródło
14
To rozwiązanie jest dobre dla widoku mobilnego, ale pokazuje animację pokaż / ukryj na dużych ekranach po kliknięciu łącza.
Ayman Al-Absi
22
@ AymanAl-Absi Trzeba dodać .indo końca data-targetwartości: data-target=".navbar-collapse.in". Z komentarza w tej odpowiedzi: stackoverflow.com/a/21797534/89818
caw
to działa świetnie dla mnie, ale zrywa scrollspy, jakiś pomysł, dlaczego tak może być?
Craig Harley,
1
Zadziałało dla mnie po zaktualizowaniu powyższego kodu z odpowiedzią @caw. Używam również funkcji scrollspy.
Niraj
To zdecydowanie najlepsze rozwiązanie. Bez javascript, bez jQuery. Jeśli chcesz, aby dany link pozostawił otwarte menu, po prostu nie dodawaj tych parametrów. Należy wskazać jako najlepszą odpowiedź. Dziękuję Ci.
ed1nh0
55

Miałem ten sam problem, ale spowodowany przez dołączenie dwukrotnie bootstrap.js i jquery.jsplików.

Za jednym kliknięciem zdarzenie zostało przetworzone dwukrotnie przez obie instancje jquery. Jeden zamknięty, a drugi otwarty.

raisercostin
źródło
3
Miałem dokładnie ten sam problem, ale nie zdawałem sobie sprawy, że zostały uwzględnione dwukrotnie. Dzięki za opublikowanie tego!
Brian ONeil
2
Tak też zrobił nasz stażysta. Dzięki za opublikowanie tego.
Teisman,
2
Człowiek! Zrobiłem to samo - chyba wróciłem do stażu!
Dicer,
2
Tak pomocny! Pracowałem nad tym przez kilka dni. Może to być bardzo częste w przypadku korzystania z szablonu paska nawigacyjnego. Uważajcie ludzie! :)
Matt Butler
2
Należy to oznaczyć jako najlepszą odpowiedź. Miałem ten sam problem z usunięciem bootstrap.js rozwiązał problem
katwekibs
17
$(".navbar-nav li a").click(function(event) {
    if (!$(this).parent().hasClass('dropdown'))
        $(".navbar-collapse").collapse('hide');
});

Pomogłoby to w obsłudze menu rozwijanego na pasku nawigacyjnym

Chakradhar Vyza
źródło
To rozwiązało mój problem polegający na tym, że używanie bootstrap z javascript z pokazu slajdów jssor powodowało problemy. Ten kod tworzy również fajny efekt podczas rozwijania i zwijania mobilnego menu.
Adam West
Dzięki @Chakradhar, to zaoszczędziło mi czasu.
Omar Bahir
Dzięki, zapomniałem, że Laravel 5.5 JS zawiera B i Jquery w głównym pliku js.
Jack Vial
12

Mam / miałem podobne problemy z Bootstrap 4, alpha-6, a powyższa odpowiedź Joakima Johanssona poprowadziła mnie w dobrym kierunku. Nie wymaga javascript. Umieszczenie data-target = ". Navbar-collapse" i data-toggle = "collapse" w znaczniku DIV wewnątrz elementu nawigacyjnego, ale otaczającego linki / przyciski, działało dla mnie.

<div class="navbar-nav" data-target=".navbar-collapse" data-toggle="collapse">
   <a class="nav-item nav-link" href="#">Menu Item 1</a>
   ...
</div>

Paweł
źródło
Twój post bardzo mi pomógł. To rozwiązało problem dla mnie <body data-toggle = "collapse" data-target = ". Navbar-collapse">
Dessus,
To było już opublikowane 3 lata temu. Dodatkowo przerywa animację w widoku niemobilnym.
Bevor
6

Wiem, że to pytanie dotyczy Bootstrap 3, ale jeśli szukasz rozwiązania dla Bootstrap 4 , po prostu zrób to:

$(document).on('click','.navbar-collapse.show',function(e) {
  $(this).collapse('hide');
});
Syed
źródło
Używam BS4 beta i Twój kod działa doskonale. Wypróbowałem wszystkie inne sugerowane rozwiązania tutaj bez powodzenia. BS4 najwyraźniej zmienił się na tyle, że inne rozwiązania po prostu nie mają zastosowania.
Bicycle Dave
Ze względu na znaczenie i zgodność z aktualnymi informacjami - to powinna być najlepsza odpowiedź.
Ricky,
@Ricky OP określił Bootstrap 3, a nie 4.
Malavos
W przypadku menu z rozwijanymi menu użyłem tego:$(".navbar-nav li a:not('.dropdown-toggle')") .on('click', function () { $('.navbar-collapse').collapse('hide'); }
James Wilkins
5

Miałem ten sam problem, używałem jQuery-1.7.1i bootstrap 3.2.0. Zmieniłem moją wersję jQuery na najnowszą ( jquery-1.11.2) wersję i wszystko działa dobrze.

Densol
źródło
5

Zrobiłem

$(".navbar-toggle").click(function(event) {
    $(".navbar-collapse").toggle('in');
});
weaveoftheride
źródło
4

Chociaż rozwiązanie opublikowane wcześniej, aby zmienić samą pozycję menu, jak poniżej, działa, gdy menu znajduje się na małym urządzeniu, ma efekt uboczny, gdy menu jest na pełnej szerokości i rozwinięte, może to spowodować przesuwanie się poziomego paska przewijania po pozycje menu . Rozwiązania javascript nie mają tego efektu ubocznego.

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

(przepraszam, że odpowiadam w ten sposób, chciałem dodać komentarz do tej odpowiedzi, ale wydaje mi się, że nie mam wystarczającego uznania, aby zgłosić uwagi)

Wim Van Houts
źródło
2
 $(function(){ 
    var navMain = $("#your id");
    navMain.on("click", "a", null, function () {
      navMain.collapse('hide');
    });
});
Pętak
źródło
sprawdź nową wersję Matthias S :-)
Chit
@bfontaine Najpierw musisz dodać id w swoim div menu, a kiedy klikniesz na menu, ostatecznie menu zostanie ukryte. Na przykład: - Po kliknięciu w menu o nas zakładka menu odpoczynku zostanie ukryta.
Chit,
1
dziękuję, ale napisz to w swojej odpowiedzi;)
bfontaine
1

Jeśli chcesz ręcznie zmienić to zachowanie, wywołując .collapse ('hide') w dyrektywie kątowej, oto kod:

plik javascript:

angular
  .module('yourAppModule')
  .directive('btnAutoCollapse', directive);

function directive() {
  var dir = {
    restrict: 'A',
    scope: {},
    link: link
  };
  return dir;

  function link(scope, element, attrs) {    
    element.on('click', function(event) {              
      $(".navbar-collapse.in").collapse('hide');
    });
  }
}

HTML:

<li class="navbar-btn">
     <a href="#" ng-hide="username" **btn-auto-collapse**>Sign in</a>
</li>
Mirna De Jesus
źródło
1

Upewnij się, że używasz najnowszej wersji bootstrap js. Miałem ten sam problem i po prostu uaktualnienie pliku bootstrap.js z bootstrap-3.3.6 zrobiło magię.

Aman Arun
źródło
1

Jeśli chcesz, aby nawigacja przełączała się tylko wtedy, gdy jest używana na ekranie telefonu komórkowego, po prostu dodaj data-toggle="collapse"idata-target="#navbar" do elementów a będzie działać na ekranie urządzenia mobilnego, ale po kliknięciu na ekranie komputera spowoduje dziwne migotanie. Rozwiązania jQuery nie działają dobrze, jeśli jesteś w środowisku Aurelia lub Angular.

Najlepszym rozwiązaniem dla mnie było utworzenie atrybutu niestandardowego, który nasłuchuje odpowiedniego zapytania o media i w data-toggle="collapse"razie potrzeby dodaje atrybut:

<a href="#" ... collapse-toggle-if-less768 data-target="#navbar"> ...

Atrybut niestandardowy z Aurelia wygląda następująco:

import {autoinject} from 'aurelia-framework';

@autoinject
export class CollapseToggleIfLess768CustomAttribute {
  element: Element;

  constructor(element: Element) {
    this.element = element;
    var mql = window.matchMedia("(min-width: 768px)");
    mql.addListener((mediaQueryList: MediaQueryList) => this.handleMediaChange(mediaQueryList));
    this.handleMediaChange(mql);
  }

  handleMediaChange(mediaQueryList: MediaQueryList) {
    if (mediaQueryList.matches) {
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");
      if (dataToggle) {
        this.element.attributes.removeNamedItem("data-toggle");
      }
    } else {
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");
      if (!dataToggle) {
        var dataToggle = document.createAttribute("data-toggle");
        dataToggle.value = "collapse";
        this.element.attributes.setNamedItem(dataToggle);
      }
    }
  }
}

witam
źródło
0

Odkryłem, że po wielu zmaganiach, próbach i błędach, najlepsze rozwiązanie dla mnie na jsfiddle. Link do inspiracji na jsfiddle.net . Używam navbar-fixed-top programu bootstrap z funkcją zwijania i przełączania hamburgera. Oto moja wersja na jsfiddle: jsfiddle Scrollspy navbar . Uzyskiwałem tylko podstawową funkcjonalność, korzystając z instrukcji na getbootsrap.com. Dla mnie problem tkwił głównie w niejasnych kierunkach i js zalecanych przez witrynę getbootstrap. Najlepsze było to, że dodanie tego dodatkowego fragmentu js (który zawiera niektóre elementy wymienione w powyższych wątkach) rozwiązało kilka problemów związanych ze Scrollspy, w tym:

  1. Zwinięte / przełączone menu nawigacyjne ukrywa się po kliknięciu "sekcji" nawigacji (np. Href = "# foobar") (problem dotyczący tego wątku).
  2. Aktywna „sekcja” została pomyślnie podświetlona (tj. Pomyślnie utworzono js class = „active”)
  3. Irytujący pionowy pasek przewijania znajdujący się w zwiniętej nawigacji (tylko na małych ekranach) został wyeliminowany.

UWAGA: W kodzie js pokazanym poniżej (z drugiego linku jsfiddle w moim poście):

topMenu = $ ("# myScrollspy"),

... wartość „myScrollspy” musi odpowiadać jej id = „” w kodzie HTML, tak jak to jest ...

<nav id="myScrollspy" class="navbar navbar-default navbar-fixed-top">

Oczywiście możesz zmienić tę wartość na dowolną wartość.

Adam Calihman
źródło
0

Wszystko, czego potrzebujesz, to data-target = ". Navbar-collapse" w przycisku, nic więcej.

<button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
    <span class="sr-only">Toggle navigation</span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
</button>
Marodo
źródło
+1: Działa również poprzez dodanie data-toggle = "collapse" data-target = ". Navbar-collapse" do <a /> lub w moim przypadku <Link /> w Meteorjs z React, dziękuję.
Joe L.
tak, to działa, <a/>ale nie działa <NavLink/>, załamuje się, ale już <NavLink/>nie działa, jakieś pomysły dlaczego?
Piramida
0

Oto kod, który zadziałał dla mnie:

jQuery('document').ready(function()
{   
   $(".navbar-header button").click(function(event) {
   if ($(".navbar-collapse").hasClass('in'))
   {  $(".navbar-collapse").slideUp();  }
});})
Roddy P. Carbonell
źródło
0

Miałem ten sam problem, upewnij się, że plik bootstrap.js znajduje się na twojej stronie html. W moim przypadku menu otworzyło się, ale się nie zamknęło. Jak tylko dołączyłem plik js bootstrap, wszystko po prostu działało.

Elitmiar
źródło
0

Prosty Spróbuj utworzyć funkcję w javascript dla rozwijanej klasy zwijania.

Przykład:

JS :

$scope.toogleMyClass  = function(){

    //dropdown-element

    $timeout(function(){
        $scope.preLoader = false;
        $(document).ready(function() {
            $("#dropdown-element").toggleClass('show');
        });
    },100);

};

Połącz tę funkcję z onClickprostymi pracami dla mnie.

yasir_mughal
źródło
0

Miałem podobny problem, ale mój nie pozostawał otwarty, otwierał / zamykał się szybko. Odkryłem, że ładowałem jquery-1.11.1.min.js przed bootstrap.min.js. Więc odwróciłem kolejność tych 2 plików i naprawiłem moje menu. Działa teraz bez zarzutu. Mam nadzieję, że to pomoże

Vasko
źródło
0

Problem może polegać na tym, że używasz nieaktualnych wersji bootstrap lub jquery, LUB wywołujesz więcej niż jedną wersję w swoim znaczniku.

Po prostu zachowaj najnowsze wersje, potrzebujesz tylko jednego odniesienia. Rozwiązuje problem.

Nacięcie
źródło
0

możesz po prostu upewnić się, że ładujesz swoje pliki ATF jQuery i Bootstrap.min.js. Twoja nawigacja jest pierwszą rzeczą do renderowania na stronie, więc jeśli masz skrypty na dole kodu HTML, tracisz wszelkie funkcje JavaScript.

Chris Johnson
źródło
0

Miałem ten sam problem tylko na telefonie komórkowym, ale w aplikacji Angular i tak właśnie zrobiłem:

app.component.html

<nav class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <div class="col-md-12">
      <div class="navbar-header page-scroll">
      <button id ="navButton" style="color:red"type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" routerLink="/"><img id="navbrand" class="site-logo"  src="assets/img/yayaka_logo.png"/></a>
    </div>
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <li class="hidden">
          <a href="#page-top"></a>
        </li>
        <li class="dropdown" appDropdown>
          <a class="dropdown-toggle" style="cursor: pointer;">
            ΤΙ ΕΙΝΑΙ ΤΟ yayaka<span class="caret"></span>
          </a>
          <ul class="dropdown-menu">
            <li><a (click) = "closeMenu()" href="/#about">About</a></li>
            <li><a (click) = "closeMenu()" href="/#services">Services</a></li>
          </ul>
        </li>
        <li class="page-scroll">
          <a (click) = "closeMenu()" routerLink="/profiles"><strong>Profiles</strong></a>
        </li>
      </ul>
    </div>
  </div>
  </div>
</nav>

app.component.ts

 closeMenu() {
    var isMobile = /iPhone|iPad|iPod|BlackBerry|Opera Mini|IEMobile|Android/i.test(navigator.userAgent);
    if (isMobile) {
      document.getElementById('navButton').click();
    }
  }

Mam nadzieję, że to pomoże :)

stathoula
źródło
-2

Moje menu nie jest standardowe w pasku nawigacyjnym, ale udało mi się automatycznie zwinąć moje, używając funkcji „onclick” i „.click ()”.

<div class="main-header">
    <div class="container">
        <div id="menu-wrapper">
            <div class="row">

                <div class="logo-wrapper col-lg-4 col-md-6 col-sm-7 hidden-xs">

                </div> <!-- /.logo-wrapper -->

                <div class="logo-wrapper2 visible-xs col-xs-9">

                </div> <!-- /.smaller logo-wrapper -->

                <div class="col-lg-8 col-md-6 col-sm-5 col-xs-3 main-menu text-center">
                    <ul class="menu-first hidden-md hidden-sm hidden-xs">
                        <li class="active"><a href="#">item1</a></li> |
                        <li><a href="#our-team">item2</a></li> |
                        <li><a href="#services">item3</a></li> |
                        <li><a href="#elia">item4</a></li> |
                        <li><a href="#portfolio">item5</a></li> |
                        <li><a href="#contact">item6</a></li>
                    </ul>
                    <a href="#" class="toggle-menu visible-md visible-sm visible-xs"><i class="fa fa-bars"></i></a>
                </div> <!-- /.main-menu -->
            </div> <!-- /.row -->
        </div> <!-- /#menu-wrapper -->
        <div class="menu-responsive hidden-lg">
            <ul>
                <li class="active" onclick = $(".toggle-menu").click();><a href="#">item1</a></li>
                <li><a href="#our-team" onclick = $(".toggle-menu").click();>item2</a></li>
                <li><a href="#services" onclick = $(".toggle-menu").click();>item3</a></li>
                <li><a href="#elia" onclick = $(".toggle-menu").click();>item4</a></li>
                <li><a href="#portfolio" onclick = $(".toggle-menu").click();>item5</a></li>
                <li><a href="#contact" onclick = $(".toggle-menu").click();>item6</a></li>
            </ul>
        </div> <!-- /.menu-responsive -->
    </div> <!-- /.container -->
</div> <!-- /.main-header 
Bravo Stefane
źródło