Bootstrap Navbar without jQuery

While I’m fond of Bootstrap in general, I dislike how much it relies on JavaScript and particularly dislike its dependency on jQuery. I have nothing against using JavaScript for creating interactive content, e.g. web applications, or progressive enhancement, e.g. lightboxes or copying text to the clipboard, but I do take issue with requiring JavaScript for basic site functionality as is the case with Bootstrap’s navbar and dropdowns. What I particularly dislike is that not only does this require JavaScript, but it requires a 32kB JavaScript library, jQuery, to do what would otherwise take less than 1kB of JavaScript. To avoid this when redesigning campworkcoeman.org, I made some modifications to open the navbar’s dropdowns on hover on larger devices and used a small piece of plain JavaScript to operate the menu on small, mobile devices. Unfortunately, this didn’t work properly under iOS, but I recently fixed this. I’m detailing the changes I made in case someone finds them useful.

As far as HTML goes, the only change is using <div> elements instead of <a> elements for the dropdown-toggle class. In the CSS, a media query is used to open the dropdowns on hover on larger devices, and some code is added to restore the appearance of the dropdowns due to the HTML change.

/*
 * Open dropdowns on hover instead of click.
 */
@media (min-width: 768px) {
  .dropdown:hover {
    background: #e7e7e7;
  }
  .dropdown:hover > .dropdown-menu {
    display: block;
  }
}

/*
 * The following is needed since the dropdowns are <div>
 * elements instead of <a> elements
 */
.nav > li > div {
  position: relative;
  display: block;
  padding: 10px 15px;
  cursor: default;
}
.navbar-nav > li > div {
  padding-top: 15px;
  padding-bottom: 15px;
  line-height: 20px;
}
.navbar-default .navbar-nav > li > div {
  color: rgb(119, 119, 119);
}
.navbar-collapse.collapse {
  display: none;
}
.dropdown-open {
  background: #e7e7e7;
}

Finally, a small script replaces the default Bootstrap bootstrap.js version.

// Navbar and dropdowns
var toggle = document.getElementsByClassName('navbar-toggle')[0],
    collapse = document.getElementsByClassName('navbar-collapse')[0],
    dropdowns = document.getElementsByClassName('dropdown');;

// Toggle if navbar menu is open or closed
function toggleMenu() {
    collapse.classList.toggle('collapse');
    collapse.classList.toggle('in');
}

// Close all dropdown menus
function closeMenus() {
    for (var j = 0; j < dropdowns.length; j++) {
        dropdowns[j].getElementsByClassName('dropdown-toggle')[0].classList.remove('dropdown-open');
        dropdowns[j].classList.remove('open');
    }
}

// Add click handling to dropdowns
for (var i = 0; i < dropdowns.length; i++) {
    dropdowns[i].addEventListener('click', function() {
        if (document.body.clientWidth < 768) {
            var open = this.classList.contains('open');
            closeMenus();
            if (!open) {
                this.getElementsByClassName('dropdown-toggle')[0].classList.toggle('dropdown-open');
                this.classList.toggle('open');
            }
        }
    });
}

// Close dropdowns when screen becomes big enough to switch to open by hover
function closeMenusOnResize() {
    if (document.body.clientWidth >= 768) {
        closeMenus();
        collapse.classList.add('collapse');
        collapse.classList.remove('in');
    }
}

// Event listeners
window.addEventListener('resize', closeMenusOnResize, false);
toggle.addEventListener('click', toggleMenu, false);

I modified Bootstrap’s navbar example to demonstrate this.

This entry was posted in and tagged , , , . Bookmark the permalink.

8 Responses to Bootstrap Navbar without jQuery

  1. thednp says:

    If you are looking to contribute to a broader project on this idea, feel free to join forces here
    http://thednp.github.io/Native-Javascript-for-Bootstrap/

  2. Tomas Repik says:

    Thank you very much! This is what I was trying to do myself and couldn’t with my little expertise. You’re my hero! I’ll mention your name in comments.

  3. Goonerify says:

    Thanks a lot. This saved me a lot of time and headaches

  4. Michiel says:

    Looks good. Can you make one for the new Bootstrap v4 as well?

  5. Pooja More says:

    This really helped me. Thank you so much for the code :) It saved my time.

  6. ket4up says:

    Your bootstrap.js in es6 syntax.

    const classChildren = x => document.getElementsByClassName(`navbar-${x}`)[0];

    classChildren(‘toggle’).addEventListener(‘click’, () => {
    classChildren(‘collapse’).classList.toggle(‘collapse’);
    }, false);

    All we do is binding the ‘hamburger’ button click action to toggle the dropdown menu.

  7. Peter says:

    Sadly, the dropdown cannot be opened by keyboard in your version…

Leave a Reply

Your email address will not be published. Required fields are marked *