[jquery] Hide Twitter Bootstrap nav collapse on click

This is not a submenu dropdown, the category is class li as in the picture:

enter image description here

By selecting a category from the responsive menu (the template is just one page), I want to hide nav collapse automatically when clicking. Also stroll to use as navigation, since the template has only one page. I seek a solution that does not affect it, here is the HTML code of menu:

    <!-- NAVBAR
  ================================================== -->
<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container">
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      </a>
      <a class="brand" href="#">Carousel Demo</a>
      <div class="nav-collapse">
        <ul class="nav" >
          <li class="active"><a href="#home">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#portfolio">Portfolio</a></li>
          <li><a href="#services">Services</a></li>
          <li><a href="#contact">Contact</a></li>
          <!-- dropdown -->
        </ul>
        <!-- /.nav -->
      </div>
      <!--/.nav-collapse -->
    </div>
    <!-- /.container -->
  </div>
  <!-- /.navbar-inner -->
</div>
<!-- /.navbar -->

This question is related to jquery html twitter-bootstrap

The answer is


Bootstrap sets a .in class on the Collapse element to trigger the animation – to open it. If you simply remove the .in class, the animation doesn't run, but will hide the element – not exactly what you want.

Likely faster to run an if statement to check if the default bootstrap class .in has been set on the element.

So this code just says:

if my element has the class .in applied, close it by triggering the default Bootstrap animation. Otherwise run the default Bootstrap action/animation of opening it

$('#navbar a').on('click touchstart', function() {
    // if .in class is set on element, the element is visible – you want to hide it
    if ($('#navbar').hasClass('in')) {
        // collapse toggle will remove the .in class and animate the element closed 
        $('#navbar').collapse('toggle');
    }
})

100% working:-

Add in HTML

<div id="myMenu" class="nav-collapse">

Javascript

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

I posted a solution that works with Aurelia here: https://stackoverflow.com/a/41465905/6466378

The problem is you can not just add data-toggle="collapse" and data-target="#navbar" to your a elements. And jQuery does not work wenn 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:

_x000D_
_x000D_
import {autoinject} from 'aurelia-framework';_x000D_
_x000D_
@autoinject_x000D_
export class CollapseToggleIfLess768CustomAttribute {_x000D_
  element: Element;_x000D_
_x000D_
  constructor(element: Element) {_x000D_
    this.element = element;_x000D_
    var mql = window.matchMedia("(min-width: 768px)");_x000D_
    mql.addListener((mediaQueryList: MediaQueryList) => this.handleMediaChange(mediaQueryList));_x000D_
    this.handleMediaChange(mql);_x000D_
  }_x000D_
_x000D_
  handleMediaChange(mediaQueryList: MediaQueryList) {_x000D_
    if (mediaQueryList.matches) {_x000D_
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");_x000D_
      if (dataToggle) {_x000D_
        this.element.attributes.removeNamedItem("data-toggle");_x000D_
      }_x000D_
    } else {_x000D_
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");_x000D_
      if (!dataToggle) {_x000D_
        var dataToggle = document.createAttribute("data-toggle");_x000D_
        dataToggle.value = "collapse";_x000D_
        this.element.attributes.setNamedItem(dataToggle);_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
$('.nav a').click(function () {_x000D_
    $('.navbar-collapse').collapse('hide');_x000D_
});
_x000D_
_x000D_
_x000D_


Even more elegant without a lick of duplicated code, is to simply apply the data-toggle="collapse" and data-target=".nav-collapse" attributes to the nav itself:

<nav class="nav-collapse" data-toggle="collapse" data-target=".nav-collapse">
  <ul class="nav">
    <li class="active"><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#portfolio">Portfolio</a></li>
    <li><a href="#services">Services</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
</nav>

Super clean, no JavaScript required. Works great, so long as your your nav a elements have plenty enough padding for fat fingers, and you aren't preventing click event bubbling via e.stopPropagation() when users click on nav a items.


On each dropdown link put data-toggle="collapse" and data-target=".nav-collapse" where nav-collapse is the name you give it to the dropdown list.

<ul class="nav" >
      <li class="active"><a href="#home">Home</a></li>
      <li><a href="#about" data-toggle="collapse" data-target=".nav-collapse">About</a></li>
      <li><a href="#portfolio" data-toggle="collapse" data-target=".nav-collapse">Portfolio</a></li>
      <li><a href="#services" data-toggle="collapse" data-target="nav-collapse">Services</a></li>
      <li><a href="#contact" data-toggle="collapse" data-target=".nav-collapse">Contact</a></li>
      <!-- dropdown -->
  </ul>

This is working perfectly on screen that have a dropdown like mobile screens, but on desktop and tablet it creates a flickr. This is because the .collapsing class is applied. To remove the flickr I created a media query and inserted overflow hidden to the collapsing class.

@media (min-width: 768px) {
.collapsing {
    overflow: inherit;
  }
}

Better to use default collapse.js methods (V3 docs, V4 docs):

$('.nav a').click(function(){
    $('.nav-collapse').collapse('hide');
});

Bootstrap3 users try the given below code. It worked for me.

function close_toggle() {
   if ($(window).width() <= 768) {
      $('.nav a').on('click', function(){
          $(".navbar-toggle").click();
      });
   }
   else {
     $('.nav a').off('click');
   }
}
close_toggle();

$(window).resize(close_toggle);

The navigation should be closed any time a user clicks anywhere on the body - not just navigation elements. Say menu is open, but user clicks in the page body. User expects to see menu close.

You also have to make sure toggle button is visible, otherwise a jump is seen in menu.

$(document).ready(function() { 

$("body").click(function(event) {
        // only do this if navigation is visible, otherwise you see jump in navigation while collapse() is called 
         if ($(".navbar-collapse").is(":visible") && $(".navbar-toggle").is(":visible") ) {
            $('.navbar-collapse').collapse('toggle');
        }
  });

});

Tested on Bootstrap 3.3.6 - work's!

_x000D_
_x000D_
$('.nav a').click(function () {_x000D_
    $('.navbar-collapse').collapse('hide');_x000D_
});
_x000D_
_x000D_
_x000D_


For those who have noticed desktop navbars flicker when using this solution:

$('.nav a').on('click', function(){
    $(".navbar-collapse").collapse('hide');
}); 

A simple solution to that problem is to reference the collapsed navbar only by checking for the presence of 'in':

$('.navbar-collapse .nav a').on('click', function(){
    if($('.navbar-collapse').hasClass('in'))
    {
        $(".navbar-collapse").collapse('hide');
    }
});

This collapses the navbar on click when the navbar is in mobile mode, but will leave alone the desktop version. This avoids the flickering many people have witnessed occurring on desktop versions.

Additionally, if you have a navbar with dropdown menus you won't be able to see these as the navbar will be hidden as soon as you click on them, so if you have dropdown menus (like I do!), use the following:

$('.nav a').on('click', function(e){
    if(!$(this).closest('li').hasClass('dropdown') & $( '.navbar-collapse').hasClass('in'))
    {
        $(".navbar-collapse").collapse('hide');
    }
});

This looks for the presence of the dropdown class above the link clicked on in the DOM, if it exists, then the link was intending to launch a drop down menu and consequently the menu isn't hidden. When you click on a link within the dropdown menu, the navbar will hide correctly.


Here's how I did it. If there is a smoother way, please please tell me.

Inside the <a> tags where the links for the menu are I added this code:

onclick="$('.navbar-toggle').click()"

It preserves the slide animation. So in full use it would look like this:

<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation" ng-controller="topNavController as topNav">
<div class="container">
    <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <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" href="home.html">My Cool Site</a>
    </div>
    <div id="navbar" class="navbar-collapse collapse">
        <ul class="nav navbar-nav">
            <li class="active" onclick="$('.navbar-toggle').click()"><a href="home.html" onclick="$('.navbar-toggle').click()"><i class="fa fa-home"></i> Home</a></li>
            <li><a href="aboutus.html" onclick="$('.navbar-toggle').click()">About Us</a></li>
        </ul>
    </div><!--/.nav-collapse -->
</div>


$(function() {
    $('.nav a').on('click', function(){ 
        if($('.navbar-toggle').css('display') !='none'){
            $('.navbar-toggle').trigger( "click" );
        }
    });
});

Adding the data-toggle="collapse" data-target=".navbar-collapse.in" to the tag <a> worked for me.

<div>

        <button type="button" class="navbar-toggle"  data-toggle="collapse" data-target=".navbar-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
    </div>
            <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                <li class="nav-item"><a
                    href="#" data-toggle="collapse" data-target=".navbar-collapse.in" class="nav-link" >Home
                </a></li>
            </ul>
    </div>

I think it's better to use default Bootstrap 3's collapse.js methods using the .navbar-collapse as the collapsible element you wish to hide as shown below.

Other solutions may cause other undesired problems with the way elements display or function in your web page. Therefore, while some solutions may appear to fix your initial problem it may very well introduce others, so make sure you run thorough testing of your site after any fix.

To see this code in action:

  1. Press "Run This Code Snippet" below.
  2. Press "Full Page" button.
  3. Scale window until drop-down activates.
  4. Then select a menu option and voila!

Cheers!

_x000D_
_x000D_
$('.nav a').click(function() {_x000D_
  $('.navbar-collapse').collapse('hide');  _x000D_
});
_x000D_
<html lang="en">_x000D_
  <head>_x000D_
    <meta charset="utf-8">_x000D_
    <meta http-equiv="X-UA-Compatible" content="IE=edge">_x000D_
    <meta name="author" content="Franciscus Agnew">_x000D_
    <meta name="viewport" content="width=device-width, initial-scale=1">_x000D_
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->_x000D_
    <title>Bootstrap Navbar Collapse Function</title>_x000D_
_x000D_
    <!-- Latest compiled and minified CSS -->_x000D_
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">_x000D_
_x000D_
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->_x000D_
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->_x000D_
    <!--[if lt IE 9]>_x000D_
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>_x000D_
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>_x000D_
    <![endif]-->_x000D_
  </head>_x000D_
  _x000D_
  <body>_x000D_
    <header>_x000D_
      <nav class="navbar navbar-default navbar-fixed-top" role="navigation">_x000D_
        <div class="container">_x000D_
          <div class="navbar-header">_x000D_
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-expanded="navbar"><span class="sr-only">Toggle navigation</span>Menu <span class="glyphicon glyphicon-chevron-down"></span></button>_x000D_
            <a class="navbar-brand" href="#">Brand Logo</a>_x000D_
          </div><!-- navbar-header -->_x000D_
    _x000D_
          <div class="collapse navbar-collapse" id="navbar">_x000D_
            <ul class="nav navbar-nav navbar-right">_x000D_
              <li class="active"><a href="#">Home</a></li>_x000D_
              <li><a href="#about">About</a></li>_x000D_
              <li><a href="#portfolio">Portfolio</a></li>_x000D_
              <li><a href="#services">Services</a></li>_x000D_
              <li><a href="#staff">Staff</a></li>_x000D_
              <li><a href="#contact">Contact</a></li>_x000D_
            </ul><!-- navbar-right -->_x000D_
          </div><!-- navbar-collapse -->_x000D_
          _x000D_
        </div><!-- container -->_x000D_
      </nav><!-- navbar-fixed-top -->_x000D_
    </header>_x000D_
    _x000D_
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->_x000D_
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>_x000D_
    _x000D_
    _x000D_
    <!-- Include all compiled plugins (below), or include individual files as needed -->_x000D_
    <!-- Latest compiled and minified JavaScript -->_x000D_
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>_x000D_
    _x000D_
    <!-- Custom Navbar Collapse Script Solution -->_x000D_
    <script>_x000D_
      $('.nav a').click(function() {_x000D_
        $('.navbar-collapse').collapse('hide');  _x000D_
      });_x000D_
    </script>_x000D_
  </body>_x000D_
</html>
_x000D_
_x000D_
_x000D_


$(function() {
    $('.nav a').on('click touchstart', function(){ 
        if($('.navbar-toggle').css('display') !='none'){
            $(".navbar-toggle").trigger( "click" );
        }
    });
});

// NOTE I added the "touchstart" for mobile touch. touchstart/end has no delay


This is the best solution I have used.

$(document).ready(function () {

        $('.nav a').on('click', function () {

            if ($(".btn-navbar").is(":visible") ){ $(".btn-navbar").trigger("click"); } //bootstrap 2.x
            if ($(".navbar-toggle").is(":visible")) { $(".navbar-toggle").trigger("click"); } //bootstrap 3.x
        });

    });

I just replicate the 2 attributes of the btn-navbar (data-toggle="collapse" data-target=".nav-collapse.in") on each link like this:

<div class="nav-collapse">
  <ul class="nav" >
    <li class="active"><a href="#home" data-toggle="collapse" data-target=".nav-collapse.in">Home</a></li>
    <li><a href="#about" data-toggle="collapse" data-target=".nav-collapse.in">About</a></li>
    <li><a href="#portfolio" data-toggle="collapse" data-target=".nav-collapse.in">Portfolio</a></li>
    <li><a href="#services" data-toggle="collapse" data-target=".nav-collapse.in">Services</a></li>
    <li><a href="#contact" data-toggle="collapse" data-target=".nav-collapse.in">Contact</a></li>
  </ul>
</div>

In the Bootstrap 4 Navbar, in has changed to show so the syntax would be:

data-toggle="collapse" data-target=".navbar-collapse.show"


Update your

<li>
  <a href="#about">About</a>
</li>

to

<li>
  <a data-toggle="collapse" data-target=".nav-collapse" href="#about">About</a>
</li>

This simple change worked for me.

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


In most cases you will only want to call the toggle function if the toggle button is visible...

if ($('.navbar-toggler').is(":visible")) $('.navbar-toggler').click();

Try this > Bootstrap 3

Brilliant exacly what I was looking for, however I had some clashes with the javascript and the bootstrap modal, this fixed it.

    $(function() {
    $('.navbar-nav').on('click', function(){ 
        if($('.navbar-header .navbar-toggle').css('display') !='none'){
            $(".navbar-header .navbar-toggle").trigger( "click" );
        }
    });
});

Hope this helps.


If you have scrolling problems after using the jQuery solution described above, e.g.

$('.navbar-collapse').collapse('toggle');

then this is caused by Bootstrap adding the CSS class overlay-active in the parent element. This can even go up to your body element.

To solve this you have to remove this class:

<script type="text/javascript">
    $(document).ready(function(){

        $('.nav-item').click(function(){
            $('.overlay-active').removeClass('overlay-active');
        });

    });
</script>

This hides nav collapse instead of animating it but same concept as above answer

JS:

$('.nav a').on('click', function () {
    $("#funk").toggleClass('in collapse');
});

HTML:

<div class="navbar-collapse" id="funk">

I prefer this on single page sites because I use localScroll.js that already animates.


Add an id then to each

<li> add data-target="myMenu" data-toggle="collapse"
<div id="myMenu" class="nav-collapse">
    <ul class="nav">
      <li class="active" data-target="myMenu" data-toggle="collapse"><a href="#home">Home</a></li>
      <li data-target="myMenu" data-toggle="collapse"><a href="#about">About</a></li>
      <li data-target="myMenu" data-toggle="collapse"><a href="#portfolio">Portfolio</a></li>
      <li data-target="myMenu" data-toggle="collapse"><a href="#services">Services</a></li>
      <li data-target="myMenu" data-toggle="collapse"><a href="#contact">Contact</a></li>
    </ul>
</div>

This worked well for me. Its the same as the accepted answer but fixes the issue related to the desktop/tablet view

_x000D_
_x000D_
$('.navbar-nav a').on('click', function () {_x000D_
        if (window.innerWidth <= 768) {_x000D_
            $(".navbar-toggle").click();_x000D_
        }_x000D_
    });
_x000D_
_x000D_
_x000D_


$("body,.nav a").click(function (event) {

    // only do this if navigation is visible, otherwise you see jump in
    //navigation while collapse() iS called 
    if ($(".navbar-collapse").is(":visible") && $(".navbar-toggle").is(":visible")) {
    $('.navbar-collapse').collapse('toggle');
  }
});

I'm on Bootstrap 4, using fullPage.js with a fixed top nav, and tried everything listed here, with mixed results.

  • Tried the best, clean way :

    data-toggle="collapse" data-target=".navbar-collapse.show"
    

    The menu would collapse, but the href links wouldn't lead anywhere.

  • Tried the logical other ways :

    $('myClickableElements').on('click touchstart', function(){
      $(".navbar-collapse.show").collapse('hide');
      // or
      $(".navbar-collapse.show").collapse('toggle');
      // or
      $('.navbar-toggler').click()
    });
    

    There would be some weird behavior because of the touchstart event : the clicked buttons would end up not be the ones I actually clicked, hence breaking the links. Plus it would add the .show class to some other unrelated dropdowns in my nav, causing some more weird stuff.

  • Tried to change div to li
  • Tried to e.preventDefault() and e.stopPropagation()
  • Tried and tried more

Nothing would work.

So, instead, I had the (so far) marvelous idea of doing that :

$(window).on('hashchange',function(){
   $(".navbar-collapse.show").collapse('hide');
});

I already had stuff in that hashchange function, si I just had to add this line.

It actually does exactly what I want : collapsing the menu when the hash changes (i.e. a click leading somewhere else has occurred). Which is good, cause I can now have links in my menu that won't collapse it.

Who knows, maybe this will help someone in my situation!

And thanks to everyone who has participated in that thread, lots of info to be learned here.


Mobile view: how to hide toggle navigation in bootstrap + dropdown + jquery + scrollto with navigation items that points to anchors/ids on the same page, one page template

The issue I was experimenting with any of the above solutions was that they are collapsing only the submenu items, while the navigation menu doesn't collapse.

So I did my thought.. and what can we observe? Well, every time we/the users click an scrollto link, we want the page to scroll to that position and contemporaneously, collapse the menu to restore the page view.

Well... why not to assign this job to the scrollto functions? Easy :-)

So in the two codes

// scroll to top action
$('.scroll-top').on('click', function(event) {
    event.preventDefault();
    $('html, body').animate({scrollTop:0}, 'slow');

and

// scroll function
function scrollToID(id, speed){
var offSet = 67;
var targetOffset = $(id).offset().top - offSet;
var mainNav = $('#main-nav');
    $('html,body').animate({scrollTop:targetOffset}, speed);
if (mainNav.hasClass("open")) {
    mainNav.css("height", "1px").removeClass("in").addClass("collapse");
    mainNav.removeClass("open");
}

I've just added the same command in both the functions

    if($('.navbar-toggle').css('display') !='none'){
    $(".navbar-toggle").trigger( "click" );
}

(kudos to one of the above contributors)

like this (the same should be added to both the scrolls)

$('.scroll-top').on('click', function(event) {
    event.preventDefault();
    $('html, body').animate({scrollTop:0}, 'slow');
if($('.navbar-toggle').css('display') !='none'){
    $(".navbar-toggle").trigger( "click" );
}
});

if you wanna see it in action just check it out recupero dati da NAS


I checked in menu is opened by checking 'in' class and then run the code.

$('.navbar-collapse a').on('click', function(){
    if ( $( '.navbar-collapse' ).hasClass('in') ) {
        $('.navbar-toggle').click();
    }
});

works perfectly.


Another quick solution for Bootstrap 3.* could be:

$( document ).ready(function() {
    //
    // Hide collapsed menu on click
    //
    $('.nav a').each(function (idx, obj) {
        var selected = $(obj);

        selected.on('click', function() {
            if (selected.closest('.collapse.in').length > 0) {
                $('.navbar-toggle').click(); //bootstrap 3.x by Richard
            }
        });
    });
});

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to twitter-bootstrap

Bootstrap 4: responsive sidebar menu to top navbar CSS class for pointer cursor How to install popper.js with Bootstrap 4? Change arrow colors in Bootstraps carousel Search input with an icon Bootstrap 4 bootstrap 4 responsive utilities visible / hidden xs sm lg not working bootstrap.min.js:6 Uncaught Error: Bootstrap dropdown require Popper.js Bootstrap 4 - Inline List? Bootstrap 4, how to make a col have a height of 100%? Bootstrap 4: Multilevel Dropdown Inside Navigation