Le menu réduit de Bootstrap 3 ne se ferme pas au clic

122

J'ai une navigation plus ou moins standard de 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>

Il s'effondre normalement sur les appareils plus petits. Cliquer sur le bouton de menu développe le menu mais si je clique (ou touche d'ailleurs) sur un lien de menu, le menu reste ouvert. Que dois-je faire pour le refermer?

Paranoïa
la source
5
la réponse de user3669917 est certainement la réponse la plus simple et la plus directe!
Thomas le
1
Copie

Réponses:

48

Le paramètre par défaut de Bootstrap est de garder le menu ouvert lorsque vous cliquez sur un élément de menu. Vous pouvez remplacer manuellement ce comportement en appelant .collapse('hide');l'élément jQuery que vous souhaitez réduire.

VCNinc
la source
8
C'est faux, bootstrap active automatiquement la classe "collapse". Vous n'avez besoin d'aucun code jquery supplémentaire. Si vous avez un tel comportement, cela signifie que quelque chose ne va pas dans votre code html (pour ma part j'inclus deux fois jquery et bootstrap, voir la réponse de @raisercostin).
RomOne
@RomOne Cette réponse est correcte. Bootstrap ne ferme pas le menu après avoir cliqué sur les liens par défaut. L'autre réponse est uniquement applicable si les gens comprennent mal jQuery deux fois qui n'est pas la bonne réponse à cette question.
Zim
136

Juste pour partager cela à partir de solutions sur GitHub, c'était la réponse populaire:

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

Ceci est connecté au document, vous n'avez donc pas à le faire sur ready () (vous pouvez ajouter dynamiquement des liens à votre menu et cela fonctionnera toujours), et il n'est appelé que si le menu est déjà développé. Certaines personnes ont signalé un clignotement étrange à l'endroit où le menu s'ouvre puis se ferme immédiatement avec un autre code qui ne vérifie pas que le menu a la classe «in».

[UPDATE 2014-11-04] apparemment lors de l'utilisation de sous-menus, ce qui précède peut causer des problèmes, donc ce qui précède a été modifié pour:

$(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a:not(".dropdown-toggle")') ) {
        $(this).collapse('hide');
    }
});
Kevin Nelson
la source
1
Fonctionne parfaitement. Merci d'avoir partagé!
Rodrigo Chiong
Pouvez-vous expliquer '$ (this) .collapse (' hide ');' S'il vous plaît. Je ne comprends pas d'où vient `` l'effondrement ''
timebandit
@ImranNazir, désolé, c'est bien après la question, mais collapsec'est une méthode définie par bootstrap et attachée à l'objet jQuery ... vraisemblablement, ils le réutilisent à des fins multiples (accordéon, barre de navigation, etc.): getbootstrap.com/javascript / # collapse-usage
Kevin Nelson
Le code mis à jour a fonctionné pour moi, les réponses ci-dessus n'ont pas fonctionné. Merci!
RandomUs1r
La "[UPDATE 2014-11-04]" a fonctionné. Quant à l'autre solution où il recommande de supprimer la référence en double à bootstrap.js et jquery qui n'est pas nécessaire la solution. J'ai trouvé cette solution pour résoudre le problème avec moins de temps pour le débogage et avec un comportement plus explicite. Je vous remercie!. J'espère que cela vous aide comme cela m'a aidé.
Nour Lababidi
122

Change ça:

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

pour ça:

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

Ce simple changement a fonctionné pour moi.

Réf: https://github.com/twbs/bootstrap/issues/9013

FullStackDev
la source
14
Cette solution convient à la vue mobile, mais elle affiche une animation afficher / masquer sur de grands écrans une fois le lien cliqué.
Ayman Al-Absi
22
@ AymanAl-Absi Vous devez ajouter .inà la fin de la data-targetvaleur: data-target=".navbar-collapse.in". Du commentaire de cette réponse: stackoverflow.com/a/21797534/89818
caw
cela fonctionne très bien pour moi mais cela brise le scrollspy, une idée de pourquoi cela pourrait être?
Craig Harley
1
A travaillé pour moi lors de la mise à jour du code ci-dessus avec la réponse @caw. J'utilise également la fonction scrollspy.
Niraj
C'est de loin la meilleure solution. Pas de javascript, pas de jQuery. Si vous voulez que certains liens gardent le menu ouvert, n'ajoutez simplement pas ces paramètres. Doit être indiqué comme la meilleure réponse. Je vous remercie.
ed1nh0
55

J'ai eu le même problème mais causé par l'inclusion de deux fois bootstrap.js et des jquery.jsfichiers.

En un seul clic, l'événement a été traité deux fois par les deux instances de jquery. L'un fermé et l'autre ouvert la bascule.

raisin
la source
3
J'ai eu exactement le même problème mais je ne savais pas qu'ils étaient inclus deux fois. Merci d'avoir publié ceci!
Brian ONeil
2
Tout comme notre stagiaire. Merci d'avoir publié ceci.
Teisman
2
Homme! J'ai fait la même chose - je suppose que je suis redevenu stagiaire!
Dicer le
2
Tellement utile! J'avais travaillé là-dessus pendant des jours. Cela peut être très courant lors de l'utilisation d'un modèle de barre de navigation. Soyez prudent les gens! :)
Matt Butler
2
Cela devrait être marqué comme la meilleure réponse. J'ai eu le même problème en supprimant bootstrap.js a résolu le problème
katwekibs
17
$(".navbar-nav li a").click(function(event) {
    if (!$(this).parent().hasClass('dropdown'))
        $(".navbar-collapse").collapse('hide');
});

Cela aiderait à gérer la liste déroulante dans la barre de navigation

Chakradhar Vyza
la source
Cela a résolu mon problème où l'utilisation de bootstrap avec le javascript d'un diaporama jssor créait des problèmes. Ce code crée également un effet sympa lors du développement et de la réduction du menu mobile.
Adam West
Merci @Chakradhar, cela m'a fait gagner du temps.
Omar Bahir
Merci, j'ai oublié que Laravel 5.5 JS inclut B et Jquery dans le fichier js principal.
Jack Vial
12

J'ai / ai eu des problèmes similaires avec Bootstrap 4, alpha-6 et la réponse de Joakim Johansson ci-dessus m'a mis dans la bonne direction. Aucun javascript requis. Mettre data-target = ". Navbar-collapse" et data-toggle = "collapse" dans la balise div à l'intérieur de la navigation, mais entourant les liens / boutons, a fonctionné pour moi.

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

Paul
la source
Votre message m'a beaucoup aidé. Cela m'a résolu le problème <body data-toggle = "collapse" data-target = ". Navbar-collapse">
Dessus
Cela a déjà été publié il y a 3 ans. En outre, cela interrompt l'animation dans la vue non mobile.
Bevor
6

Je sais que cette question concerne Bootstrap 3, mais si vous recherchez une solution pour Bootstrap 4 , faites simplement ceci:

$(document).on('click','.navbar-collapse.show',function(e) {
  $(this).collapse('hide');
});
Syed
la source
J'utilise BS4 beta et votre code fonctionne parfaitement. J'ai essayé toutes les autres solutions suggérées ici sans succès. BS4 a apparemment suffisamment changé pour que les autres solutions ne s'appliquent tout simplement pas.
Bicycle Dave
Pour la pertinence et pour garder les choses concurrentes avec des informations mises à jour - Cela devrait être la meilleure réponse.
Ricky
@Ricky OP a spécifié Bootstrap 3, pas 4.
Malavos
Pour les menus avec des listes déroulantes, j'ai utilisé ceci:$(".navbar-nav li a:not('.dropdown-toggle')") .on('click', function () { $('.navbar-collapse').collapse('hide'); }
James Wilkins
5

J'ai eu le même problème, j'utilisais jQuery-1.7.1et bootstrap 3.2.0. J'ai changé ma version jQuery pour la dernière jquery-1.11.2version ( ) et tout fonctionne bien.

Densol
la source
5

J'ai fait

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

Bien que la solution publiée plus tôt pour modifier l'élément de menu lui-même, comme ci-dessous, fonctionne lorsque le menu est sur un petit appareil, elle a un effet secondaire lorsque le menu est en pleine largeur et développé, cela peut entraîner le glissement d'une barre de défilement horizontale sur votre éléments de menu . Les solutions javascript n'ont pas cet effet secondaire.

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

(désolé d'avoir répondu comme ça, je voulais ajouter un commentaire à cette réponse, mais il semble que je n'ai pas suffisamment de crédit pour faire des remarques)

Wim Van Houts
la source
2
 $(function(){ 
    var navMain = $("#your id");
    navMain.on("click", "a", null, function () {
      navMain.collapse('hide');
    });
});
Chit
la source
vérifier la nouvelle version Matthias S :-)
Chit
@bfontaine Tout d'abord, vous devez ajouter un identifiant dans votre menu div, et lorsque vous cliquez sur votre menu, après tout, le menu sera masqué. Par exemple: - Lorsque vous cliquez sur le menu à propos de nous, l'onglet du menu de repos sera masqué.
Chit
1
merci, mais s'il vous plaît écrivez cela dans votre réponse;)
bfontaine
1

Si vous souhaitez remplacer manuellement ce comportement en appelant .collapse ('hide') dans une directive angulaire, voici le code:

fichier 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
la source
1

Veuillez vous assurer que vous utilisez la dernière version de bootstrap js. J'étais confronté au même problème et la simple mise à niveau du fichier bootstrap.js à partir de bootstrap-3.3.6 a fait la magie.

Aman Arun
la source
1

Si vous voulez que votre navigation bascule uniquement lorsqu'elle est utilisée sur un écran mobile, le simple fait d'ajouter data-toggle="collapse"et data-target="#navbar"à vos éléments fonctionnera sur l'écran mobile, mais vous donnera un scintillement étrange lorsque vous cliquez sur un écran de bureau. Les solutions jQuery ne fonctionnent pas bien si vous êtes dans un environnement Aurelia ou Angular.

La meilleure solution pour moi était de créer un attribut personnalisé qui écoute la requête multimédia correspondante et ajoute l' data-toggle="collapse"attribut si vous le souhaitez:

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

L'attribut personnalisé avec Aurelia ressemble à ceci:

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

halllo
la source
0

J'ai trouvé qu'après beaucoup de difficultés, d'essais et d'erreurs, la meilleure solution pour moi sur jsfiddle. Lien vers l'inspiration sur jsfiddle.net . J'utilise navbar navbar-fixed-top de bootstrap avec repli et bascule hamburger. Voici ma version sur jsfiddle: jsfiddle Scrollspy navbar . Je n'obtenais que les fonctionnalités de base en utilisant les instructions sur getbootsrap.com. Pour moi, le problème était principalement dans les directions vagues et js recommandées par le site getbootstrap. La meilleure partie était que l'ajout de ce bit supplémentaire de js (qui inclut une partie de ce qui est mentionné dans les fils ci-dessus) a résolu plusieurs problèmes de Scrollspy pour moi, notamment:

  1. Le menu de navigation réduit / basculé se masque lorsque le navigateur "section" (par exemple, href = "# foobar") est cliqué (problème pour traiter ce fil).
  2. La "section" active a été mise en surbrillance avec succès (c.-à-d. Js a créé avec succès class = "active")
  3. La barre de défilement verticale ennuyeuse trouvée sur la navigation réduite (uniquement sur les petits écrans) a été éliminée.

REMARQUE: Dans le code js ci-dessous (à partir du deuxième lien jsfiddle dans mon message):

topMenu = $ ("# myScrollspy"),

... la valeur "myScrollspy" doit correspondre à l'id = "" dans votre HTML comme ceci ...

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

Bien sûr, vous pouvez modifier cette valeur pour la valeur que vous souhaitez.

Adam Calihman
la source
0

Tout ce dont vous avez besoin est data-target = ". Navbar-collapse" dans le bouton, rien d'autre.

<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
la source
+1: Cela fonctionne également en ajoutant data-toggle = "collapse" data-target = ". Navbar-collapse" à <a /> ou dans mon cas <Link /> dans Meteorjs avec React, merci.
Joe L.
oui ça marche avec <a/>mais ça n'a pas fonctionné avec <NavLink/>, ça s'effondre mais ça <NavLink/>ne marche plus, des idées pourquoi?
La pyramide du
0

C'est le code qui a fonctionné pour moi:

jQuery('document').ready(function()
{   
   $(".navbar-header button").click(function(event) {
   if ($(".navbar-collapse").hasClass('in'))
   {  $(".navbar-collapse").slideUp();  }
});})
Roddy P. Carbonell
la source
0

J'ai eu le même problème, assurez-vous que bootstrap.js est inclus dans votre page html. Dans mon cas, le menu s'est ouvert mais ne s'est pas fermé. Dès que j'ai inclus le fichier bootstrap js, tout a fonctionné.

Elitmiar
la source
0

Simple Essayez de créer une fonction en javascript pour la classe de réduction déroulante.

Exemple:

JS :

$scope.toogleMyClass  = function(){

    //dropdown-element

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

};

Accrochez cette fonction à onClickdes œuvres simples pour moi.

yasir_mughal
la source
0

J'ai eu le même problème mais le mien ne restait pas ouvert, il s'ouvrirait / se fermerait rapidement, j'ai trouvé que jquery-1.11.1.min.js se chargeait avant bootstrap.min.js. J'ai donc inversé l'ordre de ces 2 fichiers et corrigé mon menu. Fonctionne parfaitement maintenant. J'espère que ça aide

Vasko
la source
0

Le problème peut être que vous utilisez des versions obsolètes de bootstrap ou jquery, OU que vous appelez plus d'une version dans votre balisage.

Gardez simplement les dernières versions, vous n'avez besoin que d'une seule référence. Résout le problème.

pseudo
la source
0

vous voudrez peut-être simplement vous assurer que vous chargez votre ATF jQuery et Bootstrap.min.js. Votre navigation est la première chose à afficher sur la page, donc si vous avez vos scripts au bas de votre HTML, vous perdez toute fonctionnalité JavaScript.

Chris Johnson
la source
0

J'ai eu le même problème uniquement sur mobile mais pour une application Angular et c'est ce que j'ai fait:

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

J'espère que ça aide :)

Stathoula
la source
-2

Mon menu n'est pas une barre de navigation standard, mais j'ai réussi à réduire automatiquement le mien, en utilisant une fonction "onclick" et un ".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
la source