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