Paranoia
Paranoia

Reputation: 2070

Bootstrap 3 collapsed menu doesn't close on click

I have a more or less standard navigation from 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>

It collapses normally on smaller devices. Clicking on the menu button expands the menu but if I click (or touch for that matter) on a menu link, the menu stays open. What do I have to do, to close it again?

Upvotes: 126

Views: 228324

Answers (24)

stathoula
stathoula

Reputation: 1740

I had the same issue only on mobile but for an Angular application and this is what I did:

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

Hope it helps :)

Upvotes: 1

Syed
Syed

Reputation: 16513

I know this question is for Bootstrap 3 but if you are looking solution for Bootstrap 4, just do this:

$(document).on('click','.navbar-collapse.show',function(e) {
  $(this).collapse('hide');
});

Upvotes: 6

Kevin Nelson
Kevin Nelson

Reputation: 7663

Just to share this from solutions on GitHub, this was the popular answer:

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

This is wired to the document, so you don't have to do it on ready() (you can dynamically append links to your menu and it will still work), and it only gets called if the menu is already expanded. Some people have reported weird flashing where the menu opens and then immediately closes with other code that did not verify that the menu had the "in" class.

[UPDATE 2014-11-04] apparently when using sub-menus, the above can cause problems, so the above got modified to:

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

Upvotes: 138

Chit
Chit

Reputation: 293

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

Upvotes: 3

Taylor Johnson
Taylor Johnson

Reputation: 484

you may want to just ensure you're loading your jQuery and Bootstrap.min.js ATF. Your navigation is the first thing to render on the page, so if you have your scripts in the bottom of your HTML, you're losing any JavaScript functionality.

Upvotes: 0

Paul
Paul

Reputation: 149

I am having/had similar issues with Bootstrap 4, alpha-6, and Joakim Johanssons answer above started me in the right direction. No javascript required. Putting data-target=".navbar-collapse" and data-toggle="collapse" into the div tag inside the nav, but surrounding the links/buttons, worked for me.

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

Upvotes: 13

halllo
halllo

Reputation: 977

If you only want your navigation to toggle when used on a mobile screen, just adding data-toggle="collapse" and data-target="#navbar" to your a elements will work on the mobile screen, but will give you a weird flicker when clicked on a desktop screen. The jQuery solutions do not work well if you are in an Aurelia or Angular environment.

The best solution for me was to create a custom attribute that listens to the corresponding media query and adds in the data-toggle="collapse"attribute if desired:

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

The custom attribute with Aurelia looks like this:

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

Upvotes: 1

Nick
Nick

Reputation: 315

The problem could be you are using out of date versions of bootstrap or jquery, OR you are calling more than one version in your markup.

Just keep the latest versions, you only need the one reference. Solves the problem.

Upvotes: 0

Vasko
Vasko

Reputation: 257

I had the similar issue but mine wouldn't stay open it would open/close quickly, I found that I had jquery-1.11.1.min.js loading before bootstrap.min.js. So I reversed the order of those 2 files and fixed my menu. Runs flawlessly now. Hope it helps

Upvotes: 0

yasir_mughal
yasir_mughal

Reputation: 112

Simple Try to make a function in javascript for dropdown collapse class.

Example:

JS:

$scope.toogleMyClass  = function(){

    //dropdown-element

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

};

Hook this function to onClick simple works for me.

Upvotes: 0

Elitmiar
Elitmiar

Reputation: 36829

I had the same problem, ensure that bootstrap.js is included in your html page. In my case the menu opened but did not close. As soon as I included the bootstrap js file, everything just worked.

Upvotes: 0

Roddy P. Carbonell
Roddy P. Carbonell

Reputation: 865

This is the code that worked for me:

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

Upvotes: 1

Aman Arun
Aman Arun

Reputation: 11

Please make sure You are using latest bootstrap js version. I was facing the same problem and just upgrading the bootstrap.js file from bootstrap-3.3.6 did the magic.

Upvotes: 1

Bravo Stefane
Bravo Stefane

Reputation: 1

My menu is not a navbar standard one, but i managed to auto collapse mine, using an "onclick" function and a ".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 

Upvotes: -2

Marodo
Marodo

Reputation: 111

All you need is data-target=".navbar-collapse" in the button, nothing else.

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

Upvotes: 0

Chakradhar Vyza
Chakradhar Vyza

Reputation: 285

$(".navbar-nav li a").click(function(event) {
    if (!$(this).parent().hasClass('dropdown'))
        $(".navbar-collapse").collapse('hide');
});

This would help in handling drop down in nav bar

Upvotes: 17

weaveoftheride
weaveoftheride

Reputation: 4395

I did

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

Upvotes: 6

FullStackDev
FullStackDev

Reputation: 1569

Change this:

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

to this:

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

This simple change worked for me.

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

Upvotes: 127

Mirna De Jesus
Mirna De Jesus

Reputation: 209

In case you want to manually override this behaviour by calling .collapse('hide') within an angular's directive, here is the code:

javascript file:

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>

Upvotes: 1

Densol
Densol

Reputation: 135

I had the same problem, I was using jQuery-1.7.1 and bootstrap 3.2.0. I changed my jQuery version to the latest (jquery-1.11.2) version and everything works well.

Upvotes: 5

Acal
Acal

Reputation: 31

I found that after much struggle, trial and error, the best solution for me on jsfiddle. Link to inspiration on jsfiddle.net. I am using bootstrap's navbar navbar-fixed-top with collapse and hamburger toggle. Here is my version on jsfiddle: jsfiddle Scrollspy navbar. I was only getting basic functionality using the instructions on getbootsrap.com. For me, the problem was mostly in the vague directions and js recommended by the getbootstrap site. The best part was that adding this extra bit of js (which does include some of what is mentioned in the above threads) solved several Scrollspy issues for me including:

  1. Collapsed/toggled nav menu hides when nav "section" (e.g. href="#foobar") is clicked (issue addressing this thread).
  2. Active "section" was successfully highlighted (ie. js successfully created class="active")
  3. Annoying vertical scroll bar found on collapsed nav (only on small screens) was eliminated.

NOTE: In the js code shown below (from the second jsfiddle link in my post):

topMenu = $("#myScrollspy"),

...the value "myScrollspy" must match it the id="" in your HTML like so...

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

Of course you can change that value to whatever value you like.

Upvotes: 0

Wim Van Houts
Wim Van Houts

Reputation: 594

Though the solution posted earlier to change the menu item itself, like below, works when the menu is on a small device, it has a side effect when the menu is on full width and expanded, this can result in a horizontal scrollbar sliding over your menu items. The javascript solutions do not have this side-effect.

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

(sorry for answering like this, wanted to add a comment to that answer, but, seems I haven't sufficient credit to make remarks )

Upvotes: 4

raisercostin
raisercostin

Reputation: 9189

I had the same problem but caused by including twice bootstrap.js and jquery.js files.

On a single click the event was processed twice by both jquery instances. One closed and one opened the toggle.

Upvotes: 55

VCNinc
VCNinc

Reputation: 757

Bootstrap's default setting is to keep the menu open when you click on a menu item. You can manually override this behaviour by calling .collapse('hide'); on the jQuery element that you want to collapse.

Upvotes: 47

Related Questions