mrspoonzy at gmail Cube by Noah Ellman A powerful javascript toolkit, in research © by Noah Ellman

JavaScript DOM Extending

This article will explain the controversial subject of JavaScript DOM extending. Learn how to do in your own framework. Learn the difference between how it was done originally in the older browsers ( IE 7.0 and before ), and the powerful exciting new way - and the future of the Javascript Language and DOM. JWee uses DOM-Extensions natively. JQuery uses the DOM Wrapping arquitecture. Two philisophies, and two frameworks. Although what is better remains much an opinion for now, eventially the gavel will come down and somebody will become absolete.

About The DOM

A DOM element is any HTML element on the page, be it a <DIV>, a <SPAN> a <INPUT>, or anything. For the purpose of this article, things we won't consider DOM elements are blocks of texts and the special html elements such as <option> or <param>.

Every HTML element in JavaScript is has properties and methods (or functions) that are built into it, because they are essentially part of the JavaScript language. For example, the html element that creates a textbox has the function select() built into it.

So considering you have a <input> element with the id of "search_box":


That code would cause the textbox to highlight itself and its current text. This is a built-in DOM method for all <INPUT> elements.

The WC3 has and continues to try to develop standards that browsers that should follow. They have defined what methods different elements should have, or what methods all elements should have.

Naturally, every flavor of browser has its own set of quirks in regards to this. Some official DOM methods are missing from some browsers, and some browsers have decided to add new methods that are not official.

What Is "DOM Extending"

One of the most exciting things in the latest generation of browsers is the ability to add your own functionality to the DOM. Let us say we want to create a totally new method for all HTML elements. Pretend for some special reason we want to add a new method to all <INPUT> elements called turnRed(), that turns the background of the input box red.

This is the WC3 standard way to do this:

HTMLInputElement.prototype.turnRed = function() { = "red";

// Or Add a function to ALL elements
HTMLElement.prototype.turnRed = function() { ... }

// Internet Explorer does not follow the standard
// HTMLElement is simply Element in IE
Element.prototype.turnRed = function() { ... }

In the above code note these two important things.

  • We added the function to the prototype of the master DOM class for INPUT's.
  • The keyword this in our new function refers to the element, and JavaScript will always know it.

Once this code has been executed by the browser all <input> elements on the page will magically have a new built-in method called turnRed(). So, now you could simply:

// in raw Javascript

// or same thing in Jwee

// Every element will have the new method

// Run through all input boxes on the page
// in raw Javascript
var inputs = document.getElementsByTagName('input');
for( var i = 0; i < inputs.length; i++ ) {

// Same as above but in JWee syntax'input').each( function() { this.turnRed(); } );

It is not really possible to just add methods to elements directly and expect them to work.

// This will not work like you think it will!
wee('#search_box').turnRed = function() {"pink"; };

Why can't we just add functions like the example above? Because JavaScript is not this smart, and it will not know what this is. By default this would actually be the same as window, or possibly another object - depending on where in your code your new function was called. It is all about the this identifier, and what is it bound (or binded) to!

When a function is added to the prototype of an object, the this reference will be permanently bound to new instances (or new elements) of the same type. This is a part of the javascript lanaguage.

Pseudo-DOM Extensions

Back a few years ago, the JavaScript language (and browsers) did not support DOM extensions. However, people found work-arounds. The popular JavaScript Framework Prototype is famous for so-called "magic" methods it adds to elements, and indeed it was quite nifty then.

This is not necessary to understand, but I will explain it nevertheless.

This is what Prototype ( does in essence:

// Create our new magic dom method as a normal function.
function turnRed() { = "red";

// Now make a copy of the turnPink method that is permanently binded to the particular element.
$('myElement').turnRed = function() { 

	// Call the global turnRed function via the .call method, passing the object that will become the this keyword
	// The ".call()" is something that is built-into JavaScript functions since the beginning of time. $('myElement') ); 

The point of the above code is to show how every element that has a turnRed() has to have a new function added to it, on-the-fly, which wraps around the global function. This creates a big overhead on system resources and speed. Rather than adding 1 new method to the prototype of the DOM, you are creating possibly hundreds of functions which are copies of each other.

Now, I believe that Prototype has since upgraded their framework to take advantage of the new way, and will use it when it's possible.

Utilizing the latest DOM Extending abilities, supported in IE 8+, Chrome, Firefox, Opera, and Safari is the way to go when building a framework for the future. This is the direction that the JavaScript language and DOM is going - towards the more advanced abilities of languages like Java and C++, which provide a reusable, scalable, and extendable OO arquitecture.

What Is DOM Wrapping?

"DOM Wrapping" is an entirely different philosophy in building a JavaScript framework.

DOM Wrapping is in fact what the the jQuery framework is founded on, and it is so rooted in this design that it's probably not possible for jQuery to ever break away from it.

Explanation and arguments coming soon....

Discussion on /blog/Javascript_DOM_Extending

TheDoctor 11/05/14 :  

Oh wait, duh, nvm. Try-catch it.

TheDoctor 11/05/14 :  

In this: how do you make it so that IE doesn't give an error when you use HTMLElement? I can't get it not to...