html

css

twitter-bootstrap

navigation

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?

Solution 1

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

Solution 2

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

Solution 3

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.

Solution 4

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.

Solution 5

$(".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

Solution 6

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>

Solution 7

I did

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

Solution 8

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

Solution 9

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.

Solution 10

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 )

Solution 11

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

Solution 12

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>

Solution 13

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.

Solution 14

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

Solution 15

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

Solution 16

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

Solution 17

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.

Solution 18

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>

Solution 19

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.

Solution 20

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.

Solution 21

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

Solution 22

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.

Solution 23

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.

Solution 24

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