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ąć?


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ąć.


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

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


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.


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


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>


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

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.


5

Zrobiłem

$(".navbar-toggle").click(function(event) {
    $(".navbar-collapse").toggle('in');
});

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)


2
 $(function(){ 
    var navMain = $("#your id");
    navMain.on("click", "a", null, function () {
      navMain.collapse('hide');
    });
});

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>

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


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


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ść.


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>

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

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.


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.


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


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.


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.


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


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