Where to Discuss?

Local Group

Preface

Goal: Javascript choice for bootstrap navigation bar.

As default bootstrap use jQuery for navigation bar. You require this for both burger button and dropdown. If what you need is only the navigation bar, you might consider to use plain javascript to make your site lighter. You might also consider other javascript such as Vue or other, so here we need to learn to get rid of jQuery, and use Vue version of navigation bar javascript.


4: jQuery

Bootstrap come with jQuery as default and does not provide any choice. jQuery used to be a good choice one decade ago. And jQuery usage are declining time after time.

In order for the burger button and dropdown to works, we need javascript however.

Prepare The Head

Consider jQuery in the <head> element.

<head>
  ...

  <link rel="stylesheet" type="text/css" href="assets/css/bootstrap.css">
  <link rel="stylesheet" type="text/css" href="assets/css/main.css">

  <script src="assets/js/jquery-slim.min.js"></script>
  <script src="assets/js/bootstrap.min.js"></script>
</head>

You do not need anything else, and your burger menu would just works.

Burger Button

Add burger button in the <nav> element.

  <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
    ...

    <button class="navbar-toggler" type="button" 
        data-toggle="collapse" data-target="#navbarCollapse" 
        aria-controls="navbarCollapse" aria-expanded="false" 
        aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarCollapse">
      ...
    </div>
  </nav>

Responsive

Consider have a look at the result in small screen, and click the burger button to open the menu. The expected result of clicked will be:

Bootstrap Navigation Bar: jQuery Burger Button

And also click the dropdown menu.

Bootstrap Navigation Bar: jQuery Dropdown Menu


5: Plain

How about port the script to native?

The only thing I need for my blog is the navbar, so why should I need jQuery? How about port the functionality to native script?

Prepare The Head

Consider this small script in the <head> element.

<head>
  ...

  <link rel="stylesheet" type="text/css" href="assets/css/bootstrap.css">
  <link rel="stylesheet" type="text/css" href="assets/css/main.css">

  <script src="assets/js/bootstrap-navbar-native.js"></script>
</head>

This is all you need.

The Script

Luckily I found this good link below, so that I do not need to reinvent the wheel.

The burger button can be done with this script below:

document.addEventListener("DOMContentLoaded", function(event) { 
  // Check for click events on the navbar burger icon
  var toggler = document.getElementsByClassName('navbar-toggler')[0];
  var collapse = document.getElementById('navbarCollapse');
  
  // Toggle if navbar menu is open or closed
  function toggleMenu() {
    collapse.classList.toggle('show');
    console.log('Toggle show class in navbar burger menu.');
  }
  
  // Event listeners
  toggler.addEventListener('click', toggleMenu, false);
});

And the complete script for dropdown menu, can simplified as script below:

document.addEventListener("DOMContentLoaded", function(event) { 
  // Check for click events on the navbar burger icon
  var toggler = document.getElementsByClassName('navbar-toggler')[0];
  var collapse = document.getElementById('navbarCollapse');
  var dropdownButton = document.getElementById('navbarDropdown');
  var dropdownMenu   = document.querySelector('[aria-labelledby="navbarDropdown"]');
  
  // Toggle if navbar menu is open or closed
  function toggleMenu() {
    collapse.classList.toggle('show');
    console.log('Toggle show class in navbar burger menu.');
  }

  function toggleDropdown() {
    dropdownMenu.classList.toggle('show');
    console.log('Toggle show class in dropdown submenu.');
  }
  
  // Close dropdowns when screen becomes big enough to switch to open by hover
  function closeMenusOnResize() {    
    if (collapse.classList.contains('show')) {
        console.log('Remove show class before collapsing.');
        dropdownMenu.classList.remove('show');
    }
  }

  // Event listeners
  window.addEventListener('resize', closeMenusOnResize, false);
  toggler.addEventListener('click', toggleMenu, false);
  dropdownButton.addEventListener('click', toggleDropdown, false);
});

I do not port the transition part. And not all behaviour is ported to this native javascript. I simply have no interest for too much effort.


6: Vue

The decade of jQuery has been left in the past. Now we have a some better javascript framework as an option. Well, Vue is not the only option. You may choose other javascript framework.

Prepare The Head

Consider Vue in the <head> element.

<head>
  ...

  <link rel="stylesheet" type="text/css" href="assets/css/bootstrap.css">
  <link rel="stylesheet" type="text/css" href="assets/css/main.css">
  <script src="assets/js/vue.min.js"></script>
  <script src="assets/js/bootstrap-navbar-vue.js"></script>
</head>

Burger Button

We need to alter the script a bit. The burger button in the <nav> element is a little bit different.

  <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"
       id="navbar-vue-app">
    ...

    <button class="navbar-toggler" type="button"
        @click="toggleOpenMenu"
        data-toggle="collapse" data-target="#navbarCollapse"
        aria-controls="navbarCollapse" aria-expanded="false" 
        aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarCollapse"
         v-bind:class="{'show': isOpenMenu}">
      ...
    </div>
  </nav> 

Burger Javascript

The Javascript will examine the #navbar-vue-app element.

document.addEventListener("DOMContentLoaded", function(event) { 
  console.log('Document is Ready.');

  new Vue({
    el: '#navbar-vue-app',
    data: {
      isOpenMenu: false
    },
    methods: {
      toggleOpenMenu: function (event) {
        this.isOpenMenu = !this.isOpenMenu;
        console.log('Toggle show class in navbar burger menu.');
      }
    }
  });
});

I got the script from:

And I did a few adjustment to make it suitable for bootstrap.

With the same logic we can apply to code to dropdown submenu.

      <ul class="navbar-nav mr-auto">
        <li class="nav-item active dropdown">
          <a class="nav-link dropdown-toggle" id="navbarDropdown"
             @click="toggleOpenSubmenu" 
             href="#" role="button" data-toggle="dropdown" 
             aria-haspopup="true" aria-expanded="false">Archives
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown"
               v-bind:class="{'show': isOpenSubmenu}">
            <a class="dropdown-item" href="#">By Tags</a>
            <a class="dropdown-item" href="#">By Category</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="#">By Chronology</a>
          </div>
        </li>
        <li class="nav-item active">
          <a class="nav-link" href="#">About</a>
        </li>
      </ul>

Complete Javascript

The Javascript will examine the #navbar-vue-app element.

document.addEventListener("DOMContentLoaded", function(event) { 
  console.log('Document is Ready.');

  new Vue({
    el: '#navbar-vue-app',
    data: {
      isOpenMenu: false,
      isOpenSubmenu: false
    },
    methods: {
      toggleOpenMenu: function (event) {
        this.isOpenMenu = !this.isOpenMenu;
        console.log('Toggle show class in navbar burger menu.');
      },
      toggleOpenSubmenu: function (event) {
        this.isOpenSubmenu = !this.isOpenSubmenu;
        console.log('Toggle show class in dropdown submenu.');
      },
      onResize(event) {
        if (this.isOpenSubmenu) {
          console.log('Remove show class before collapsing.');
          this.isOpenSubmenu = false;
        }
      }
    },
    mounted() {
      // Register an event listener when the Vue component is ready
      window.addEventListener('resize', this.onResize)
    },
    beforeDestroy() {
      // Unregister the event listener before destroying this Vue instance
      window.removeEventListener('resize', this.onResize)
    }
  });

});

Responsive

The expected result of clicked button burger is similar native above.


What is Next ?

Now you can get rid of jQuery peacefully. For the rest of the tutorial I will use the light native javascript.

There are more, about Navigation Bar in Bootstrap. Consider continue reading [ Bootstrap - Navigation Bar - Icons ].

Thank you for reading.