Is there an agreed set of \"best practices\" for use of the DOM Level 0 collections in modern JavaScript applications? (document.forms
, document.images
First off, great question.
DOM Level 0-1 functionality is my favorite toolbox to work with. The support is tremendous. I'll highlight the pros and cons for each subset of DOM Level 0 below:
Since these are added as properties of an ElementNode, you can only have one handler. For some instances (eg: event delegation), this is burdensome. However, I feel that the DOM is diverse enough (especially as your project gets bigger) to have enough room for DOM level 0 handlers. DOM Level 2 listeners are painful to implement without a library/framework to smooth over older browsers. Even as a Flash developer (listeners are used everywhere), the DOM 0 events are far easier to me. One of the highlights is the fact that the this
value is set for you (without IE hacking and coughing like the other model). For example, consider this markup:
Now, all that needs to be done is selection and attachment of a DOM Level 0 handler.
var foo = document.getElementById("foo");
function bar()
{
console.log(this); //
}
foo.onclick = bar;
That's a very easy way of selecting elements and an alternative to Event.currentTarget;
There's a great discussion on DOM Level 0 events vs. DOM Level 2 events here: [link]
DOM Level 0 HTMLCollections
Bar none, HTMLCollections are my favorite feature of the DOM. Because nodes are selected for you, there's no need to run queries. In my opinion, they're the most overlooked DOM feature today. Name traversal such as: collection["name"]
is very handy and certainly helps when traversing forms. For example, consider this bit of markup:
There are many DOM Level 0 ways to tackle this.
var foo = document.forms.foo; //
Demo: http://jsbin.com/udozoz/0edit#preview
var foo = document.forms[0]; //
Demo: http://jsbin.com/udozoz/2/edit#preview
var foo = document.getElementById("foo"); //
Demo: http://jsbin.com/udozoz/3/edit#preview
Certainly, method 3 is more preferable. It's DOM Level 1, and not DOM Level 0. However, name traversal fits naturally for the HTMLFormElement.elements HTMLCollection. Since you're supposed to use name
attributes on form elements, you can easily access them without an id
attribute.
Ex: var baz = foo.elements.baz;
When using radio buttons that share the same name (to make only one selectable at a time), you can use the HTMLFormElement.elements HTMLCollection to select all of the radio buttons. That's very powerful. Consider this markup:
You could use this simple code and have every radio button with the name
attribute value of "selectable":
var foo = document.forms.foo;
var selectables = foo.elements.selectable;
console.log(selectables); //[input#select_1 a, input#select_2 b, input#select_3 c]
Demo: http://jsbin.com/upiyom/edit#preview
var foo = document.forms.foo;
var selectables = foo.selectable;
console.log(selectables); //[input#select_1 a, input#select_2 b, input#select_3 c]
Demo: http://jsbin.com/upiyom/2/edit#preview
Option 2 enables you to bypass the elements
HTMLCollection completely. While certainly not as clear as Option 1, it's still used today.
HTMLCollections have become more populous and far more diverse since the introduction of DOM Level 0. For example, take a look at the HTMLCollections available for a table. It's staggering. There's HTMLTableElement.rows, HTMLTableElement.tBodies, HTMLTableSectionElement (thead, tbody, tfoot).rows, and HTMLTableRowElement.cells. Those collections are very powerful, and have made DOM traversal far simpler with tables (permitting you use them).
DOM Level 0 Properties
While the properties on ElementNodes weren't as diverse in DOM Level 0 as they are now, there's still a couple of gems to note:
HTMLInputElement.defaultChecked
defaultChecked
enables you to bypass searching through an HTMLInputElement's checked
attribute completely because it stores a boolean based on that attribute's value. This means you don't have to kludge through sloppy solutions for IE builds related to get/set/removeAttribute. Later on, the defaultValue
property would also be added to fill a similar need.
document.lastModified [non-standard]
lastModified
will store the last time the document was changed. It's a cool little feature that has limited use.
HTMLDocument.title
title
will snag the document's title for you. Its usage is a small niche at best.
In regards to your tbody
question, browsers today do add an HTMLTableSectionElement (tbody) if you don't to promote proper DOM structure. You should get to know proper table markup so this won't be a problem in the future :).
Example markup:
Wrong:
Hello, World!
Right:
Hello, World!
Demo: http://jsbin.com/exomub/edit#preview
Summary
The main point that needs to be driven home is that most of DOM Level 0 is standardized in DOM Levels 1 and 2. This means the browser support is extensive (since it's really old). There shouldn't be too much apprehension to using it—aside from some edge cases in older browser builds. At the end of the day, it's your choice.
I'd like to add that I've only very briefly—in the past—been employed to develop with HTML/JavaScript. I do it as a hobby, so I'm not privy to "horror stories" about browsers/projects gone wrong.
I hope this cleared a few things up.
-Matt
ElementNode - Node with nodeType == 1
HTMLCollection - Live array-like NodeList collected by the browser