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