Vanilla Javascript or Why You Should Pay the Bandwidth Gods

TLDR version: use new built-in DOM features if you are doing REALLY BASIC DOM manipulation otherwise do yourself a favor and pay the 32kB to the bandwidth gods and save yourself some time/headache/lines of code!

I’ve Become Spoiled By jQuery

Those of you who know me know that I’ve become obsessed with d3.js lately. The selectors in d3 look a lot like jQuery but in the documentation it states it only uses Sizzle (jQuery’s selector engine) for older browsers and in modern browsers it uses the W3C Selectors API.

Huh? What the heck is that? Apparently while I’ve been living in jQuery-land there have been a ton of advances in plain vanilla Javascript (well, the DOM anyway). So let’s explore what’s new. Let’s start out with a VERY basic html structure:

<html>
  <body>
    <ul>
      <li id="foo" class="bar">Item 1</li>
      <li id="foo2" class="bar2">Item 2</li>
    </ul>
  </body>
</html>

classList API

The classList API allows you to easily add/remove/toggle classes on an html element.
Works In: Most modern browsers except IE8/9

var elem = document.getElementById('foo');
 
elem.classList.add('bar'); //#foo now has .bar
elem.classList.remove('bar'); //.bar is now removed
elem.classList.toggle('bar'); //#foo now has .bar again

querySelector / querySelectorAll API

JQuery-like selector functions that return the first matched element (querySelector) or all matched elements as a NodeList (querySelectorAll).
Works In: Every browser except IE7

//WOW this looks a LOT like jQuery
var foo = document.querySelector("#foo"); 
var bar = document.querySelector(".bar"); //returns first match
 
//querySelector is available on elements in addition to document
bar.querySelector('.foobar');
 
//return a NodeList of all .bar's inside #foo's
var bars = document.querySelectorAll("#foo .bar"); 
 
//also available on elements
bar.querySelectorAll(".foobar"); //returns all .foobar's inside bar

So far so good. Looks and feels a lot like JQuery without downloading a JS lib (awesome!). Chances are if you’re reading this you’re not using IE7 so this capability is in your browser right now. Open the console and play around with it! When I saw these in action for the first time I thought “sweet! Let’s scrap JQuery and use this”. My heart was broken though once I tried to do anything useful with the results from these two new methods.

OK Let’s Manipulate The DOM!

What is the point of selecting stuff if we’re not going to manipulate it in some way. Let’s start with some simple examples like adding/removing/toggling a class:

  //jQuery

  //add a class to one element
  $('#foo').addClass('bar');

  //add a class to many elements
  $('.foo').addClass('bar');
 
  //DOM
 
  //add a class to one element
  //classList makes this easy!
  document.querySelector("#foo").classList.add('bar');
 
  //add a class to many elements
  //holy crap that is a lot of typing for a simple example!
  for(var i = 0, foos = document.querySelectorAll('.foo'); i < foos.length; i++) {
    foos[i].classList.add('bar');
  }

Problems

The querySelectorAll method returns a NodeList object. This NodeList objects looks like an Array and acts like an Array but it’s not an Array. It’s what Javascripters call an “Array-like object”. It can be iterated over and has a length property but is missing all of the essential Array methods (forEach, map, reduce, etc.).

var lis = document.querySelectorAll('li');
 
console.log(lis.length); // 2
 
for(var i = 0; i < lis.length; i++) {
  console.log(lis[i]);
}

You *can* use Array’s map, reduce, etc methods by using some JS hackery. This will help out when we get frustrated below:

var lis = document.querySelectorAll('li');
 
//borrowing Array's methods.  .call on a method is a fancy way to
//set the this property when the method runs
 
[].forEach.call(lis, function(li) {
  console.log(li);
});
 
[].map.call(lis, function(li) { return li.id; })
//["foo", "foo2"]
 
[].reduce.call(lis, function(total, li) { 
  return total + li.id; }, "")
//"foofoo2"

You *could* add to Nodelist’s prototype but in general that’s a bad direction to go. People way smarter than me have already covered why not.

More DOM Manipulation

Now let’s try to find a sub element and alter it:

//jQuery
 
var foos = $('.foo');
...other code...
 
//now select one child element and toggle a class
foos.find('#bar').toggleClass('highlight');

//select many child elements and toggle their classes
foos.find('.bar').toggleClass('highlight');
 
//DOM
 
var foos = document.querySelectorAll('.foo');
..other code...
 
//now select one child element and toggle a class
for(var i = 0; i < foos.length; i++) {
  foos[i].querySelector('#bar').classList.toggle('highlight');
}
 
//select many child elements and toggle their classes
//really starting to appreciate jQuery at this point!
for(var i = 0; i < foos.length; i++) {
  for(var j = 0, foobars = foos[i].querySelectorAll('.bar'); j < foobars.length; j++) {
    foobars[j].classList.toggle('highlight');
  }
}

…and We Haven’t Even Covered

If you’re not convinced yet that jQuery is still far superior to Vanilla Javascript then remember we haven’t hit on Cross Browser Support, Events, .closest, .parents, etc. All stuff jQuery handles rather nicely and make us ignorant of the mess that is cross browser development.

I know that DOM manipulation is out of style currently in favor of MVC/MVVM flavor Javascript libs but if even ever need to manipulate the DOM then do yourself a favor and pay the bandwidth gods the 32kB and send a thank you note to the awesome jQuery team!!

5 Comments

  1. Mariam July 4, 2014 9:58 pm Reply

    It’s hard to find your articles in google. I found it on 20 spot, you should build quality backlinks , it will help you to rank to google top 10.
    I know how to help you, just type in google – k2 seo tricks

    http://Nickolas.blogspot.com

  2. Cathleen July 6, 2014 11:48 pm Reply

    I see a lot of interesting posts on your website.
    You have to spend a lot of time writing, i know how to save you a lot of
    time, there is a tool that creates unique, google friendly articles in couple of
    seconds, just type in google – laranita’s free content source

    http://Tyrone.blogspot.com

  3. William August 29, 2014 2:00 am Reply

    I read a lot of interesting content here. Probably you spend a lot of time writing,
    i know how to save you a lot of work, there is an online tool that creates high quality, SEO friendly posts in minutes,
    just type in google – laranitas free content source

    http://Archie.blogspot.com

  4. Fred1992 May 29, 2017 12:29 am Reply

    This article is on 12 spot in google’s search results, if you want more visitors, you should build
    more backlinks to your website, there is one trick to get free,
    hidden backlinks from authority forums, search on youtube;
    how to get hidden backlinks from forums

    https://Shanel1992.blogspot.se

  5. baseball jerseys quick yummy November 10, 2017 7:17 am Reply

    Thanks for another informative blog. Where else could I get that kind of info written in such an ideal way? I have a project that I’m just now working on, and I’ve been on the look out for such info.

    http://www.gazette.gc.ca/gazette/html-interstitial-eng-fra.php?source_pdf=/rp-pr/p2/2013/2013-06-19/pdf/g2-14713.pdf&referer=http://http://okolica.net/go.phphttp://www.jerseysshop.store

Leave a Reply to Mariam Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>