The Javascript on my site is fairly basic - controlling the mobile menu toggle and adding a class if Javascript is enabled - so it seemed silly to use jQuery just for a couple of lines. I rewrote the script in plain (or vanilla) Javascript instead of jQuery - here's a couple of key things I came across:

querySelector and querySelectorAll

Finds either the first (querySelector) or every (querySelectorAll) element which matches the selector.

classList

Calling classList returns a list of classes on the element:

<p class="text clearfix">Lorem ipsum</p>
document.querySelectorAll('p').classList
//-> text clearfix

element.classList has four functions to access or change classes on an element:

  • contains: checks whether the element has a class
  • add: add a class to the element
  • remove: remove a class
  • toggle: adds a class if not present, or removes it if it already exists

querySelector and classList allowed me to replace essentially all of the jQuery code in my script - examples below. It feels good to remove an entire library from my site! (although I am using it on the blog and project pages :P)

Original - using jQuery

// namespace code to prevent collisions or global variables leaking
var jt = jt || {};

// once the page has loaded, fire everything
$(document).ready(function() {
    jt.helpers.jsCheck();
    jt.nav.mobileMenu();
});

// navigation functions
// uses the revealing module pattern
jt.nav = (function() {

    // this hides or shows the mobile menu when the nav button is pressed
    function mobileMenu() {
        $('.nav__mobile-menu').click(function(e) {
            e.preventDefault();

            $('.nav').toggleClass('nav--active');
        });
    }

    return {
        mobileMenu: mobileMenu
    };
})();

// helper functions
jt.helpers = (function() {

    // this adds a class to the document if JS is enabled in the browser
    function jsCheck() {
        $('html').removeClass('no-js').addClass('js');
    }

    return {
        jsCheck: jsCheck
    };
})();

Updated version - plain Javascript

var jt = jt || {};

// same functions as above
jt.nav = (function() {
    function mobileMenu() {

        // querySelector returns the first element it finds with the correct selector
        // addEventListener is roughly analogous to $.on()
        document.querySelector('.nav__mobile-menu').addEventListener('click', function(e) {
            e.preventDefault();

            // querySelectorAll returns all the nodes it finds with the selector
            // however, you can't iterate over querySelectorAll results (!!)
            // so this is a workaround - call Array.map and pass in the
            // list of nodes along with a function
            // technically querySelectorAll returns a NodeList not an Array so
            /// doesn't have standard array functions
            [].map.call(document.querySelectorAll('.nav'), function(el) {

                // classList is the key here - contains functions to manipulate
                // classes on an element
                el.classList.toggle('nav--active');
            });
        });
    }

    return {
        mobileMenu: mobileMenu
    };
})();


jt.helpers = (function() {
    function jsCheck() {

        // again, use classList to manipulate classes on elements
        var bodyClass = document.querySelector('html').classList;
        bodyClass.remove('no-js');
        bodyClass.add('js');
    }

    return {
        jsCheck: jsCheck
    };
})();


// start everything
// this isn't in a doc.ready - loaded at the bottom of the page so the DOM is already ready
jt.helpers.jsCheck();
jt.nav.mobileMenu();