From jQuery to JavaScript: A Reference

From jQuery to JavaScript: A Reference

Tutorial Details
  • Subject: jQuery and JavaScript
  • Difficulty: Moderate

Whether we like it or not, more and more developers are being introduced to the world of JavaScript through jQuery first. In many ways, these newcomers are the lucky ones. They have access to a plethora of new JavaScript APIs, which make the process of DOM traversal (something that many folks depend on jQuery for) considerably easier. Unfortunately, they don’t know about these APIs!

In this article, we’ll take a variety of common jQuery tasks, and convert them to both modern and legacy JavaScript.

Modern vs. Legacy – For each item in the list below, you’ll find the modern, “cool kids” way to accomplish the task, and the legacy, “make old browsers happy” version. The choice you choose for your own projects will largely depend on your visitors.


Before We Begin

Please note that some of the legacy examples in this article will make use of a simple, cross-browser, addEvent function. This function will simply ensure that both the W3C-recommended event model, addEventListener, and Internet Explorer’s legacy attachEvent are normalized.

So, when I refer to addEvent(els, event, handler) in the legacy code snippets below, the following function is being referenced.

var addEvent = (function () {
	var filter = function(el, type, fn) {
		for ( var i = 0, len = el.length; i < len; i++ ) {
			addEvent(el[i], type, fn);
		}
	};
	if ( document.addEventListener ) {
		return function (el, type, fn) {
			if ( el && el.nodeName || el === window ) {
				el.addEventListener(type, fn, false);
			} else if (el && el.length) {
				filter(el, type, fn);
			}
		};
	}

	return function (el, type, fn) {
		if ( el && el.nodeName || el === window ) {
			el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
		} else if ( el && el.length ) {
			filter(el, type, fn);
		}
	};
})();

// usage
addEvent( document.getElementsByTagName('a'), 'click', fn);

1 – $('#container');

This function call will query the DOM for the element with an id of container, and create a new jQuery object.

Modern JavaScript

var container = document.querySelector('#container');

querySelector is part of the Selectors API, which provides us with the ability to query the DOM using the CSS selectors that we’re already familiar with.

This particular method will return the first element that matches the passed selector.

Legacy

var container = document.getElementById('container');

Pay special attention to how you reference the element. When using getElementById, you pass the value alone, while, with querySelector, a CSS selector is expected.


2 – $('#container').find('li');

This time, we’re not hunting for a single element; instead, we’re capturing any number of list items that are descendants of #container.

Modern JavaScript

var lis = document.querySelectorAll('#container li');

querySelectorAll will return all elements that match the specified CSS selector.

Selector Limitations

While nearly all relevant browsers support the Selectors API, the specific CSS selectors you pass are still limited to the capability of the browser. Translation: Internet Explorer 8 will only support CSS 2.1 selectors.

Legacy

var lis = document.getElementById('container').getElementsByTagName('li');

3 – $('a').on('click', fn);

In this example, we’re attaching a click event listener to all anchor tags on the page.

Modern JavaScript

[].forEach.call( document.querySelectorAll('a'), function(el) {
   el.addEventListener('click', function() {
     // anchor was clicked
  }, false);

  

});

The above snippet looks scary, but it’s not too bad. Because querySelectorAll returns a static NodeList rather than an Array, we can’t directly access methods, like forEach. This is remedied by calling forEach on the Array object, and passing the the results of querySelectorAll as this.

Legacy

var anchors = document.getElementsbyTagName('a');
addEvent(anchors, 'click', fn);

4 – $('ul').on('click', 'a', fn);

Ahh – this example is slightly different. This time, the jQuery snippet is using event delegation. The click listener is being applied to all unordered lists, however, the callback function will only fire if the target (what the user specifically clicked on) is an anchor tag.

Modern JavaScript

document.addEventListener('click', function(e) {
   if ( e.target.matchesSelector('ul a') ) {
      // proceed
   }
}, false);

Technically, this vanilla JavaScript method isn’t the same as the jQuery example. Instead, it’s attaching the event listener directly to the document. It then uses the new matchesSelector method to determine if the target – the node that was clicked – matches the provided selector. This way, we’re attaching a single event listener, rather than many.

Please note that, at the time of this writing, all browsers implement matchesSelector via their own respective prefixes: mozMatchesSelector, webkitMatchesSelector, etc. To normalize the method, one might write:

var matches;

(function(doc) {
   matches = 
      doc.matchesSelector ||
      doc.webkitMatchesSelector ||
      doc.mozMatchesSelector ||
      doc.oMatchesSelector ||
      doc.msMatchesSelector;
})(document.documentElement);

document.addEventListener('click', function(e) {
   if ( matches.call( e.target, 'ul a') ) {
      // proceed
   } 
}, false);

With this technique, in Webkit, matches will refer to webkitMatchesSelector, and, in Mozilla, mozMatchesSelector.

Legacy

var uls = document.getElementsByTagName('ul');

addEvent(uls, 'click', function() {
   var target = e.target || e.srcElement;
   if ( target && target.nodeName === 'A' ) {
      // proceed
   }
});

As a fallback, we determine if the nodeName property (the name of the target element) is equal to our desired query. Pay special attention to the fact that older versions of Internet Explorer sometimes plays by their own rules – sort of like the kid who eats play-doh during lunch time. You won’t be able to access target directly from the event object. Instead, you’ll want to look for event.srcElement.


5 - $('#box').addClass('wrap');

jQuery provides a helpful API for modifying class names on a set of elements.

Modern JavaScript

document.querySelector('#box').classList.add('wrap');

This new technique uses the new classList API to add, remove, and toggle class names.

var container = document.querySelector('#box');

container.classList.add('wrap'); 
container.classList.remove('wrap');
container.classList.toggle('wrap'); 

Legacy

var box = document.getElementById('box'),

    hasClass = function (el, cl) {
        var regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
        return !!el.className.match(regex);
    },

    addClass = function (el, cl) {
        el.className += ' ' + cl;
    },

    removeClass = function (el, cl) {
        var regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
        el.className = el.className.replace(regex, ' ');
    },

    toggleClass = function (el, cl) {
        hasClass(el, cl) ? removeClass(el, cl) : addClass(el, cl);

    };

addClass(box, 'drago'); 
removeClass(box, 'drago');
toggleClass(box, 'drago'); // if the element does not have a class of 'drago', add one.

The fallback technique requires just a tad more work, ay?


6 - $('#list').next();

jQuery’s next method will return the element that immediately follows the current element in the wrapped set.

Modern JavaScript

var next = document.querySelector('#list').nextElementSibling; // IE9

nextElementSibling will refer specifically to the next element node, rather than any node (text, comment, element). Unfortunately, Internet Explorer 8 and below do not support it.

Legacy

var list = document.getElementById('list'),
	next = list.nextSibling;

// we want the next element node...not text.
while ( next.nodeType > 1 ) next = next.nextSibling;

There’s a couple ways to write this. In this example, we’re detecting the nodeType of the node that follows the specified element. It could be text, element, or even a comment. As we specifically need the next element, we desire a nodeType of 1. If next.nodeType returns a number greater than 1, we should skip it and keep going, as it’s probably a text node.


7 - $('<div id=box></div>').appendTo('body');

In addition to querying the DOM, jQuery also offers the ability to create and inject elements.

Modern JavaScript

var div = document.createElement('div');
div.id = 'box';
document.body.appendChild(div);

There’s nothing modern about this example; it’s how we’ve accomplished the process of creating and injecting elements into the DOM for a long, long time.

You’ll likely need to add content to the element, in which case you can either use innerHTML, or createTextNode.

div.appendChild( document.createTextNode('wacka wacka') );

// or

div.innerHTML = 'wacka wacka';

8 – $(document).ready(fn)

jQuery’s document.ready method is incredibly convenient. It allows us to begin executing code as soon as possible after the DOM has been loaded.

Modern JavaScript

document.addEventListener('DOMContentLoaded', function() {
   // have fun
});

Standardized as part of HTML5, the DOMContentLoaded event will fire as soon as the document has been completed parsed.

Legacy

// http://dustindiaz.com/smallest-domready-ever
function ready(cb) {
	/in/.test(document.readyState) // in = loadINg
		? setTimeout('ready('+cb+')', 9)
		: cb();
}

ready(function() {
   // grab something from the DOM
});

The fallback solution, every nine milliseconds, will detect the value of document.readyState. If “loading” is returned, the document hasn’t yet been fully parsed (/in/.test(). Once it has, though, document.readyState will equal “complete,” at which point the user’s callback function is executed.


9 – $('.box').css('color', 'red');

If possible, always add a class to an element, when you need to provide special styling. However, sometimes, the styling will be determined dynamically, in which case it needs to be inserted as an attribute.

Modern JavaScript

[].forEach.call( document.querySelectorAll('.box'), function(el) {
  el.style.color = 'red'; // or add a class
});

Once again, we’re using the [].forEach.call() technique to filter through all of the elements with a class of box, and make them red, via the style object.

Legacy

var box = document.getElementsByClassName('box'), // refer to example #10 below for a cross-browser solution
   i = box.length;
 
while ( i-- > 0 && (box[i].style.color = 'red') );

This time, we’re getting a bit tricky with the while loop. Yes, it’s a bit snarky, isn’t it? Essentially, we’re mimicking:

var i = 0, len;

for ( len = box.length; i < len; i++ ) {
   box[i].style.color = 'red';
}

However, as we only need to perform a single action, we can save a couple lines. Note that readability is far more important than saving two lines – hence my “snarky” reference. Nonetheless, it’s always fun to see how condensed you can make your loops. We’re developers; we do this sort of stuff for fun! Anyhow, feel free to stick with the for statement version.


10 – $()

Clearly, our intention is not to replicate the entire jQuery API. Typically, for non-jQuery projects, the $ or $$ function is used as shorthand for retrieving one or more elements from the DOM.

Modern JavaScript

var $ = function(el) {
	return document.querySelectorAll(el);
};
// Usage = $('.box');

Notice that $ is simply a one-character pointer to document.querySelector. It saves time!

Legacy

if ( !document.getElementsByClassName ) {
	document.getElementsByClassName = function(cl, tag) {
	   var els, matches = [],
	      i = 0, len,
	      regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
	 
	   // If no tag name is specified,
	   // we have to grab EVERY element from the DOM	 
	   els = document.getElementsByTagName(tag || "*");
	   if ( !els[0] ) return false;

	   for ( len = els.length; i < len; i++ ) {
	      if ( els[i].className.match(regex) ) {
	         matches.push( els[i]);
	      }
	   }
	   return matches; // an array of elements that have the desired classname
	};
}
 
// Very simple implementation. We're only checking for an id, class, or tag name.
// Does not accept CSS selectors in pre-querySelector browsers.
var $ = function(el, tag) {
   var firstChar = el.charAt(0);
 
   if ( document.querySelectorAll ) return document.querySelectorAll(el);
 
   switch ( firstChar ) {
      case "#":
         return document.getElementById( el.slice(1) );
      case ".":
         return document.getElementsByClassName( el.slice(1), tag );
      default:
         return document.getElementsByTagName(el);
   }
};

// Usage
$('#container');
$('.box'); // any element with a class of box
$('.box', 'div'); // look for divs with a class of box
$('p'); // get all p elements

Unfortunately, the legacy method isn’t quite so minimal. Honestly, at this point, you should use a library. jQuery is highly optimized for working with the DOM, which is why it’s so popular! The example above will certainly work, however, it doesn’t support complex CSS selectors in older browsers; that task is just a wee-bit more complicated!


Summary

It’s important for me to note that that I’m not encouraging you to abandon jQuery. I use it in nearly all of my projects. That said, don’t always be willing to embrace abstractions without taking a bit of time to research the underlying code.

I’d like this posting to serve as a living document, of sorts. If you have any of your own (or improvements/clarifications for my examples), leave a comment below, and I’ll sporadically update this posting with new items. Bookmark this page now! Lastly, I’d like to send a hat-tip to this set of examples, which served as the impetus for this post.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • aoiTo

    I love this tutorial ! I need it ! Thanks you very much Jeffrey !

  • elkaz

    Great article Jeffrey. It’s fun watching the progression of a language over time :)

  • Abderrahmane TAHRI JOUTI

    Re-inventing the wheel can be foolish sometimes, but in cases like this one : just re-invent the 4 damn wheels if you can. cuz relying on a jQuery like library on every project, without ever knowing how it actually works is just too un-productive.

    Nice tutorial Jeff, thank you.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yeah – I’ve seen many single-page websites, where jQuery is exclusively being used for the purpose of fetching a couple elements from the DOM. This is wasteful…especially when the designer doesn’t realize how easy it is to do with vanilla JS.

      • http://www.justinwhall.com Justin W Hall

        Why is wasteful? In the end it does the same thing. Here’s a script used a LOT:

        //nav to anchors
        $(document).ready(function(){
        $(“.scroll”).click(function(event){
        //prevent the default action for the click event
        event.preventDefault();

        //get the full url – like mysitecom/index.htm#home
        var full_url = this.href;

        //split the url by # and get the anchor target name – home in mysitecom/index.htm#home
        var parts = full_url.split(“#”);
        var trgt = parts[1];

        //get the top offset of the target anchor
        var target_offset = $(“#”+trgt).offset();
        var target_top = target_offset.top;

        //goto that anchor by setting the body scroll top to anchor top
        $(‘html, body’).animate({scrollTop:target_top}, 900);
        });

        });

      • http://www.justinwhall.com Justin W Hall

        In the end it does the same thing with no discernible performance difference is what I meant to say :)

      • http://www.jeffrey-way.com Jeffrey Way
        Author

        Because jQuery is not necessary if your only need is to fetch a couple elements from the DOM.

      • http://raphaelddl.com RaphaelDDL

        Is good to learn old JS? Yes, because you can understand better what jquery does in the end. And because jQuery does not cover everything.

        It is good to use old JS when you have jQuery available? I don’t think so. Of course i mix both but if jquery have a short-hand, i’ll not use old JS. jQuery, minified, gzipped, etc is 30kb or less..

        Nowdays we can have the option of including it and will not sharply increase the load time, like was some years ago so i don’t see the problem.

        The only problem is people who learn jQuery and think they are ‘JS Gurus’, but don’t even know what getElementById does or how use it (even if the name itself is obvious, they would not achieve anything without ‘document.’ before.)

  • http://www.shwaark.com Capitaine Mousse

    You could use Zest (https://github.com/chjj/zest) if you only need a super optimized librairie selector

  • http://www.natehull.com Nate

    Wow. You guys had it hard. Much respect for the old days before jQuery. Glad I have not yet needed to learn this stuff, though it would be nice to have such a library of info.

    Cheers for posting

  • Nav

    For #8 isnt it every 9 milliseconds not 9 seconds? – “The fallback solution, every nine seconds..”

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      haha – yes. 9 seconds might be a bit of a stretch. :) I’ll fix that now.

      • Nav

        Great article though Jeffrey!

  • http://www.vankoder.com Don

    Minor note…in your $(document).ready() solution, you say that the setTimeout will fire every 9 seconds. That’s every 9 -milli-seconds. Every 9 seconds would be setTimeout(blah, 9000).

  • http://rawdesigns.net/ Rob

    Great resourceful post for a JavaScript ‘newbie’ like me. Definitely bookmarked.

    Cheers!

  • Vegard Aasen

    Nice article!
    Even though, I must say that after jQuery was introduced, more people tend to use js more ‘effeciently’ and clever.
    JQ fan here!:-)

  • http://www.codehunterbd.wordpress.com Khairul Alam

    Boom Boom Tutorial, really helpful to all.Thanks Jeff to share it.Thanks a lot.:)

  • kankaro

    nice article… you dissect whats inside the jQuery, @ least we have been enlighten :D

  • clayton miller

    I know this is a moderate tut example. But I was trying to play with it a bit. I tried number 9 for starters. What do I have wrong?

    http://pastebin.com/WKaSnyjj

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Hi Clayton – It looks like your pretty, curly quotes are screwing things up. Try this: http://jsbin.com/ivozom

      • clayton miller

        I dont see where the error was? Would you mind pointing out which line it was in on the pastebin file I linked to? I adjusted my code and made it identical to yours, didnt work. Pasted yours it worked. I went through it line for line. Am I blind?

        Thanks for your help!

      • http://www.jeffrey-way.com Jeffrey Way
      • clayton miller

        I just seen it before your last reply. Thats so weird. I dont know how they got there. I just replicated what I had done to try the example. And I copied and pasted from here and it created the “pretty” quotes. I just tried doing it all over again and it didn’t do it that time!

        Thanks for your time helping out a noob!

  • http://thebfdesigns.com/ejfrias EJ Frias

    Nice tutorial Jeff! Its like reading a history book. Very interesting! :)

  • Caio

    yeah. way to go Jeff.
    We don’t need no stinkin’ jQuery.

    ha.. just kiddin’ guys.

  • http://ddigangi.com Dan DiGangi

    It’s disappointing that developers think jQuery knowledge = Javascript

  • http://www.mediaheroes-webdesignbrisbane.com.au Anna Green

    I started out in life as an Artist then when I realised I would one day have bills to pay, I decided that Graphic Design was a nice evolution and something that I enjoyed, then when I decided to leave my first Graphic Design job to look for pastures new all of a sudden I was expected to know how to build websites! So I went off and retrained and now I am a Graphic Designer, Web Developer, Team Leader and Host Master but now again I find myself needing to learn something new. Now just to be current in the web world I need to be a master of java script… So off I go to a JavaScript course – Just goes to show you need to be able to adapt in life!

  • kasakka

    Very nice. It’s been so long single I’ve had to deal with this shit that I’ve forgotten most of it and wasn’t even aware of the modern ways to do things.

    Just goes to show how much easier jQuery makes pretty much everything JS related.

  • Hott Dogg

    Why don’t use RegExp.test in hasClass function? It will be much faster than .match

    var hasClass = function (element, whatClass) {
    return (new RegExp(“(^|\\s)” + whatClass + “(\\s|$)”, ‘i’)).test(element.className);
    };

    Or even without RegExp:

    var hasClass = function(element, whatClass) {
    return !!((‘ ‘ + element.className + ‘ ‘).indexOf(‘ ‘ + whatClass + ‘ ‘) + 1);
    };

    • Hott Dogg

      Sorry, a little modification to last function

      var hasClass = function(element, whatClass) {
      return (‘ ‘ + element.className + ‘ ‘).indexOf(‘ ‘ + whatClass + ‘ ‘) !== -1;
      };

      • http://fumle.dk Peter Müller

        Using indexOf without regexes will gives you false positives on substrings, so that’s not an option.

        The regexes could be simplified using wordboundaries though

        var hasClass = function (element, className) {
        return (new RegExp(‘\\b’ + className + ‘\\b’)).test(element.className);
        };

        var removeClass = function (element, className) {
        element.className = element.className.replace(new RegExp(‘\\b’ + className + ‘\\b’, ‘g’), ”);
        };

        PS: In your function using indexOf there is no reason to concatenate with empty strings. element.className is a string, and so is the argument to the function.

  • http://eknol.com Ryan

    This is awesome! Its great how some things done in jquery can be so easily done with regular javascript!

  • http://www.brianscaturro.com Brian

    When talking about limitations of querySelector and querySelectorAll, isn’t it worth mentioning the difference between a live NodeList and a static NodeList?

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      It’s mentioned in my upcoming book, but I don’t think it’s necessary for a code roundup like this. If I’m speaking specifically to jQuery users (who don’t know much vanilla JS), I’m not going to scare them by bringing up performance differences between querySelectorAll and getElementsByTagName.

  • Ebrahim Byagowi

    Thanks for great article.
    I think instead of `[].forEach.call`, `Array.prototype.forEach.call` must used.
    I created a benchmark test for this: http://jsperf.com/foreach-call

    • Dennis

      I agree with you – although we can see in the test case you have created that there isn’t a significant performance difference between the two methods, I think it is needless to create a new object [] when we can use Array.prototype.

      @Jeffrey: This is a great tutorial – honestly, I always prefer using jQuery as it removes the browser differences, but it is always important to know how to deal with the basics without any libraries :)

      • Ebrahim Byagowi

        That was my fault :P
        In this http://jsperf.com/foreach-call/3 you can see the difference between them :)
        @Author: For the second time, thanks for this great reference and article :)

  • http://francois.robichet.com/ Calvein

    The classList API is pretty bad and not really similar to jQuery because you all the method required one and only one class, that’s very annoying.

  • http://www.dynamicguru.com/mujtaba/ Mujtaba

    I cant imagine having to write all those classical code, jQuery FTW!

  • http://jakefolio Jake Smith

    One thing to note to people who, sadly, have to still support IE6. The method “getElementsByClassName” is not supported in IE6. As Jeffrey stated, you don’t need to abandon jQuery, but this information is very good to know.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yeah – that’s why I added a custom version in item 10.

  • http://www.omiod.com Omiod

    Sometime I use jQuery, sometimes I code JS for older browser, other times I just code for Chrome, so this is going to be really useful.
    I wonder if exists a jQuery version that uses just the modern code too. Should be quite slim and fast (and still neater than plain JS)

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Other times, you just code for Chrome? What does that mean?

      • http://raphaelddl.com RaphaelDDL

        Just Chrome? What kind of sorcery is this? jk.. Maybe he was trying to say for WebKit.. (High-End Mobiles, for e.g.).

        I’m curious now about that.

  • http://www.inserthtml.com/ Johnny

    Great idea for an article. There were a few here I didn’t know!

  • Luke A. Kist

    I trully love j-query the only thing I advise is where it loads from I have had a better optimized website with loading time decreased with. “use the library pointed to google that way you don’t have to worry about using the latest version this alone will increase site performance.

  • http://csmr.kapsi.fi Casimir Pohjanraito

    You have achieved Rock.

    This seems to be awesomeness.

  • Bugster

    For number 7, there’s a better way to do it that can insert JS directly:

    // From Dottoro.com – http://help.dottoro.com/ljmkgsnw.php
    if (element.insertAdjacentHTML) {
    element.insertAdjacentHTML(“beforeEnd”, html);
    }
    else {
    var df = document.createRange().createContextualFragment(html);
    element.appendChild(df);
    }

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Only if you want to use a polyfill to make Firefox 7 and below happy.

  • Darren

    Good stuff, you always maintain my learning curve. I’ve got jQuery addiction lately and I know I need to learn more vanilla (or modern) JS.

    When is your book out, and what’s in it?

  • Frank Zappa

    This is all Chinese for me lol. But in video format should be more english. The DOM seems like a video game lol. oh well lol

  • http://okeowoaderemi.com Okeowo Aderemi

    i remember the coding in JS during the pre-jQuery days i gave up on it to focus on PHP, it was damn stuff, and the browser incompatibility nearly drove me Mad,am glad i still know the basic javascript and some advanced function, but i’ll be damned to write pure JS codes when Dojo and jQuery exists. those pre-jquery days traumatized my js experience :(

  • http://techbrij.com Brij

    Ultimate Post !!!

    Very useful who started working with jQuery directly, not so much in javascript. It’s very helpful when project uses no jQuery and small task is to be done.

    Thanks for this great post !!!

  • VF

    Addition to jQuery, tutorials like this makes life much easier for javascript noobs like me. :D

  • http://dan.cx/ Daniel15

    Great article for beginners who have only experienced jQuery :)

    I wouldn’t call things like getElementById and getElementsbyTagName “legacy”. They’re still quite handy, and last time I checked, querySelector/querySelectorAll were significantly slower.

    Protip: If you put your JavaScript at the very bottom of the page, you will almost never require a DOMContentLoaded event. Since the script is at the bottom, you *know* that the DOM is ready, and so you can just run your onload JavaScript right away.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Yeah – I wasn’t sure what to call it. You’re right, though, “legacy” isn’t entirely accurate. I just needed a way to refer to the more old-school way of accomplishing tasks.

      • supprof

        thank you very mutch jeffry way
        i wanted to know if it’s possible to make us a tutorial about “.htaccess” how to redirecting and my also redifine the default filename ( i mean the “index” file) to make the website open on another pagename.
        and may be other staff usefull that you know, and i will never ever know if you’re not going to make this tutorial.
        thanks Jeffry Way.

  • http://dan.cx/ Daniel15

    Also your “Modern JavaScript” code from #3 is missing the code to actually attach the event handler :P

  • Erwin Gargalicano

    Great article!! Thanks!!

  • Colin Morgan

    I’m glad you did an article on this. I’ve been struggling with my use of jQuery for the last couple months. I’m making it a goal of mine to utilize vanilla JS more this year.

    Another good example of this situation occurring in web development is RoR. Learning a framework/library before learning the language feels oh so wrong. I guess it’s part of our new generation mentality.

  • clayton miller

    How do you test all the different ways to see which is faster? Using the DOM in firebug?

    Im a noob with js/jquery as I stated earlier in one of my comments.

    Thanks – Clayton

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Check out jsperf.com

      • http://thevocabularyworkshop.com/ Mike

        Thanks Jeffrey for sharing jsPerf.com, it really saves time and nerves while testing the code

      • Clayton Miller

        Thanks Jeffery, FYI my name on twitter is mxpimp47 I ask you random questions from time to time on there too. Just so you connect the two. Im extreme athlete / wanna be programmer hahaha. Thanks for all the good articles.

  • http://marksmits.com Mark

    Great article Jeff, really makes me want to test out even more stuff.

    Would also be very interesting to see how jQuery vs Modern score in performance. I am always looking to max out my performance in the time I have to create a project, but this far I’ve always combined the “legacy” Javascript in combination with jQuery.

    Wonder if the Modern Javascript could beat jQuery in performance.

  • http://realestatebyarmin.com Armin

    Pretty detailed explanation of the process. I really appreciate how in depth you go, especially with how complicated this can be.

  • Techeese

    nice article jeffrey thanks alot
    been looking for something like this.

  • Mj

    useful article . Modern JavaScript is so similar to actionscript, good for flash developers. thanks jeffery.

  • http://twitter.com/rwaldron Rick Waldron

    So, did no one notice that #3 is completely missing the actual event handler code? All it does is iterate…

  • http://alittlecode.com/ David Cochran

    This is a fantastic resource for my JavaScript / jQuery students. Thanks Jeffrey!

  • http://blog.pathtosharepoint.com Christophe

    I don’t understand example 3. How come the static nodeList is treated like an array?

    Nice article btw, especially the dual modern + “legacy” js. Too often people only compare jQuery to the old way.

    • http://www.xing.com/profile/Tobias_Krogh Tobias Krogh

      Nice article. It delivers a very good impression how jQuery helps us with our daily life.

      To Christophe:
      “I don’t understand example 3. How come the static nodeList is treated like an array?”

      In modern browser the array has the forEach method on the instance. So if you do [1,2,3].forEach(/* func */); it will just work as a charm. document.querySelectorAll(‘a’) delivers a nodeList that does not have such a method.

      Calling [].forEach.call(document.querySelectorAll(‘a’), /* func */); will use document.querySelectorAll(‘a’) as this inside of forEach. So we get the “forEach” function which we wanna use from an empty array and use “.call” to set the nodeList as a new “this” for the method call (which originally would be the array it is called on).

      You can find a good explanation here: http://stackoverflow.com/questions/2125714/explanation-of-slice-call-in-javascript
      They use slice but in the end it is the ame principle.

      • http://blog.pathtosharepoint.com Christophe

        Thanks Tobias, this is very helpful (and scary at the same time).

  • http://www.xing.com/profile/Tobias_Krogh Tobias Krogh

    Nice article. It gives a short but meaningful impression of what jQuery helps us with and why the world is just better when using a framework.

    @ “Christophe”
    .call is your friend. By doing [].forEach we gain the reference to the function. By using .call we bind a new owner to forEach when it is executed. So instead of iterating the empty array we just “borrow” its forEach method and execute it as if the document.querySelectorAll(‘a’) result would be the owner.

  • Dan

    This is good. It is always important to learn mechanics behind. Now, can somebody please fix the filesharing sites?

  • http://www.codylindley.com Cody Lindley

    Its great seeing this spin on the DOM. Nice work Jeffrey! I like where this is headed…and will be contributing my own voice in the near future to the notion that the DOM is not as big of a mess as it once was.

  • http://www.bacondrivencoding.com/ Sean McMillan

    In #8, you’re calling setTimeout with a string, and concatenating a function to that string. That’s bad form, even for legacy support. You really need setTimeout(function() {ready(cb);}, 9); (no strings.)

    setTimeout with a string is basically an eval.