Whether you use a JavaScript framework, or you are a purist and always resort to coding your client-side scripts from scratch, there are certain DOM methods with which you should be at least a little bit familiar.
It’s true that a library like jQuery or MooTools will perform these methods for you, behind the scenes. In fact, if you rely on JS libraries for virtually all your JavaScript code, you’ll rarely have to use any of these methods directly.
But the reality is that, whether we develop as freelancers or work for a development firm, we may not always have the luxury of working on fresh projects where we can pretty much do what we want; we may have to maintain sites that rely on “obtrusive” scripting methods, or, for one reason or another, we may not be permitted to use certain libraries.
Whatever your situation, the following review of various practical DOM methods will hopefully serve to bolster your JavaScript knowledge and possibly help you more readily see practical solutions to various client-side issues.
1. getElementById
This is a no-brainer. Every JavaScript coder should be thoroughly familiar with this method of accessing virtually any element in the DOM. Here is the syntax:
var myVariable = document.getElementById("my_element");
The accessed element can be dynamic, like this:
var myVariable = document.getElementById(myElement);
Notice the literal element has been replaced by a variable (which would be defined elsewhere).
The getElementById
method places whatever object you want to access (for example, a specific link on your page) in a variable called myVariable
, allowing you to access that object directly.
So, if you had a link on your page with its id
set to “my_element”, you could now apply the following code to that element:
myVariable.style.display = "block"; myVariable.style.backgroundColor = "#f00"; myVariable.style.border = "solid 1px #00f";
With the above code, your link will become a block-level element with a red background and a blue border.
When you first start using this method, you’ll probably be scratching your head, wondering what you’re doing wrong, trying to figure out why you’re getting an error. Just keep in mind that JavaScript is case sensitive, so you’ll commonly see this:
var myVariable = document.getElementByID("my_element");
At first glance the above code looks exactly the same as the first code block. Do you see the difference? The case of “Id” has been changed to “ID”, which is a very common mistake for beginners. But after the first few times making that mistake, this method will become old hat.
Another drawback to this method is that you have to apply an id
in your HTML to whatever method you want to access. So, while getElementById
can be very powerful, it can also encourage messy code, as it forces you to clutter your markup.
2. getElementsByTagName
If you want to keep your markup clean, this method will help you to do so. getElementsByTagName
allows you to traverse the DOM looking for all the elements on your page with a specified tag name. Here is the syntax:
var myLinkCollection = document.getElementsByTagName("a");
With that one line of code, the variable myLinkCollection
becomes an array holding all of the anchor elements on your page. There are so many ways you can take advantage of this method, so I won’t go into too many details here, but here is one powerful use for this method:
var myLinkCollection = document.getElementsByTagName("a"); for (i = 0; i < myLinkCollection.length; i++) { if (myLinkCollection[i].className == "link_class") { myLinkCollection[i].onclick = function() { this.style.backgroundColor = "#f00"; } } }
Don’t get overwhelmed if you don’t understand everything going on above. The purpose of this code snippet is to show you a practical use for the getElementsByTagName
method.
After you’ve collected your links into an array, you use a for loop
to navigate through all of them. When you find one that has the class “link_class” attached to it, you apply a click event to that link that will trigger a background color change on that object.
You might wonder: Why not just apply an id
to the link and use getElementById
to access it directly? getElementById
only allows you to access one element, since ids cannot be shared. So, with the above code, you can have many different links with the same class name, and they will all respond to the click event, which, in this case, changes the background color of the link that is clicked.
3. Node Methods
I’m sure I could write a few paragraphs on the different methods of accessing “nodes” in the DOM, but I think a basic overview of the possibilities will suffice for our purposes here. A “node” is essentially any element on your page within the DOM structure, including whitespace and text that would be in between XHTML tags.
The different node methods available through DOM manipulation are as follows:
node.childNodes
node.firstChild
node.lastChild
node.parentNode
node.nextSibling
node.previousSibling
In each case above, the italicized “node” would be the object you are referencing. Let’s illustrate the diversity of these methods using a simple example:
Suppose you have this XHTML:
<ul id="list"> <li><a href="link1.html" class="link_one">Link Number One</a></li> <li><a href="link2.html">Link Number Two</a></li> <li><a href="link3.html">Link Number Three</a></li> <li><a href="link4.html">Link Number Four</a></li> </ul>
We can access the first link in our unordered list using any one of the following 3 sections of code:
var myLinkList = document.getElementById("list"); var myFirstLink = myLinkList.childNodes[0].childNodes[0]; alert(myFirstLink.className);
var myLinkList = document.getElementById("list"); var myFirstLink = myLinkList.firstChild.firstChild; alert(myFirstLink.className);
var myLinkList = document.getElementById("list"); var myFirstLink = myLinkList.firstChild.firstChild.nextSibling.previousSibling; alert(myFirstLink.className);
The resulting “alert” message in each of the above cases will be the same: It will display the class name of the first link in the list. The same element is accessed using different node methods. The third example is especially convoluted, and not recommended; i’ve included it here for the purpose of illustrating all the node methods.
In theory, this code works — however, you won’t get the same results with every browser. Firefox, for example, will display a JavaScript error message telling you that an object is not defined –while IE7 will alert all 3 messages just fine. The reason for this is that Firefox views whitespace as a node. There are ways around this, which require checking node values to ensure that the accessed elements are legitimate objects, and not just whitespace.
So use these node methods selectively and carefully, and test them accross browsers before deploying.
4. createElement
This method does exactly what it says: it creates an element and allows you to place that new element anywhere in the DOM structure.
Using the list example from above, we could add a new list item using the following code:
var myNewListItem = document.createElement("li"); var myNewLink = document.createElement("a");
The above code creates a new <li>
element and a new anchor tag. But these elements don’t exist anywhere except as values inside variables. To add our new elements to the DOM, we can use the next method listed in this article.
5. appendChild
Let’s add the two elements we just created to our list of links using the appendChild
method:
var myNewListItem = document.createElement("li"); var myNewLink = document.createElement("a"); var myLinkList = document.getElementById("list"); myLinkList.appendChild(myNewListItem); myLinkList.lastChild.appendChild(myNewLink);
The above code adds a new anchor tag inside of a new <li>
element at the end of our link list. Keep in mind that this new element will have no attributes and will not be viewable in the source code, since it is a fresh, dynamically created element. If you’re using the Firefox Developer Toolbar, you can use the “view generated source” option to view the new element in context, but the browser’s built-in source code reader will not show you any client-side-generated markup.
This brings us naturally to our next method.
6. removeChild
In order to remove the element that we just created, we would use the following code:
var myLinkList = document.getElementById("list"); var myRemovedLink = myLinkList.lastChild; myLinkList.removeChild(myRemovedLink);
In this case, we didn’t have to remove both the list item and the anchor; removing the list item does both, since it contains the newly created anchor. Of course, if we had not created any new elements, then the above code would serve to remove the last list item, regardless of whether it was a newly created one, or one that exists naturally in our markup.
7. getAttribute
The getAttribute
method allows you to access the value of any attribute on any element on your page. For example, going back to our list of links, suppose we had the following code:
<ul id="list"> <li><a href="link1.html" class="link_one">Link Number One</a></li> <li><a href="link2.html">Link Number Two</a></li> <li><a href="link3.html">Link Number Three</a></li> <li><a href="link4.html">Link Number Four</a></li> <li><a href="link5.html" id="link_5" rel="external">Link Number Five</a></li> </ul>
We’ve added a new link with an id
of “link_5” and a rel
attribute with the value “external”.
If we want to read the rel
attribute of the fifth link in our list, we would use the following code:
var myLinkFive = document.getElementById("link_5"); var myLinkAttribute = myLinkFive.getAttribute("rel");
Now the value of the variable myLinkAttribute
will contain the rel
attribute’s value, which, in this case, is “external”. This method could be used to target links with specific rel
values so you can open those links in a new window.
8. setAttribute
Writing a new value for a given attribute is another useful method, and can be used in conjunction with getAttribute
. Let’s say we wanted to change the value of the rel
attribute from the previous example. Here’s how that is accomplished:
var myLinkFive = document.getElementById("link_5"); myLinkFive.setAttribute("rel", "nofollow");
With the above code, the fifth link in our list would now have a rel
attribute with the value “nofollow”, instead of “external”.
Keep in mind that an attribute can not only be changed, but it can be added. So, if our fifth link did not have a rel
attribute, the above code would still work, and would create the rel
attribute and assign it a value on the fly.
9. document.forms
Almost every website that you work on will have a form of some sort on it. While you can access a form or form element directly using getElementById
or another method mentioned above, the best way to access any given form is using the document.forms
syntax, which is basically acessing the “forms” collection of the document object.
For example, look at the following XHTML:
<form id="my_form" method="post" action="form.html"> <input type="checkbox" value="one" name="options" id="option1" checked="checked" /> One<br /> <input type="checkbox" value="two" name="options" id="option2" /> Two<br /> <input type="checkbox" value="three" name="options" id="option3" /> Three<br /> </form>
We could find out the “checked” state of any of the checkboxes with the following code:
var myCheckBoxOne = document.forms["my_form"]["option1"]; alert(myCheckBoxOne.checked);
In the above example, the alert message will display “true”, because the checkbox that we’re accessing (“option1”) has its checked
attribute set. If we change the code to access “option2”, the result will be an alert message of “false”.
Radio buttons are accessed similarly, but instead of being treated as separate entities (as is usually the case with checkboxes), radio buttons are accessed as one collective object. To find out which radio button in a group is selected, we can use a loop. Take a look at the following XHTML:
<form id="my_form" method="post" action="form.html"> <input type="radio" value="one" name="options" /> One<br /> <input type="radio" value="two" name="options" checked="checked" /> Two<br /> <input type="radio" value="three" name="options" /> Three<br /> </form>
And here is the loop that will alert a message that displays the “value” attribute of the selected radio button:
var radioButtonGroup = document.forms["my_form"]["options"]; for (var i = 0; i < radioButtonGroup.length; i++) { if (radioButtonGroup[i].checked == true) { alert("Your selection is " + radioButtonGroup[i].value); } }
10. innerHTML
The innerHTML
property is an interesting beast. Firstly, it is a nonstandard element, but is very well supported accross all browsers and platforms. IE evidently has a few problems when accessing this property inside of a form, but generally it has good support.
Basically, innerHTML
is a way of accessing, for the purpose of writing to, the content inside of an XHTML element. It comes in handy with Ajax requests because you can choose an element on your page, then write the Ajax-loaded content straight into that element via innerHTML
. Here’s a simple example:
var myContentHolder = document.getElementById("content"); myContentHolder.innerHTML = "<p>This is the dynamic content created by the innerHTML property</p>";
With the code above, the element on the page with the id
of “content” will now have content between its tags consisting of the text “This is the dynamic content created by the innerHTML property” wrapped in paragraph tags.
The innerHTML
element can also be read directly and appended to. (Thanks to Stacey in the comments for pointing out my error in regards to the drawbacks of this property, which I’ve corrected here.)
Know Any Other DOM Methods?
Well, I hope you enjoyed this list. I tried to cover some practical DOM methods that I’ve personally used on many projects, and even a few that I haven’t used too often but that I feel could offer solutions to various issues on the client side.
Although I didn’t delve too deeply into the intricacies of these DOM methods, I encourage all beginner and intermediate JavaScript coders to research each of these methods more fully, so as to have a stronger grasp of how the DOM is manipulated. Even if you rely heavily on JavaScript libraries, knowledge of essential DOM manipulation is a huge plus, as it helps you fully understand the different methods of accessing, adding to, and removing, page elements.
A nice collection of top JS functions/properties but you missed a bunch of the IE-Gotchas.
e.g.
getElementById() http://webbugtrack.blogspot.com/2007/08/bug-152-getelementbyid-returns.html
and getElementsByTagName() http://webbugtrack.blogspot.com/2007/09/bug-204-getelementsbytagname-doesnt.html
both have issues in IE
as does innerHTML.
http://webbugtrack.blogspot.com/2007/12/bug-210-no-innerhtml-support-on-tables.html
just thought you’d want to be aware
very well written article.. your effort is appreciated!
i think it’s great to know the behind-the-scenes stuff. at some point tho, i think actual javascript will not be written “naked” anymore, and i for one, will take any advantage i can get to write faster, cleaner code using libraries. in fact, entities that rely on “obtrusive” code are possibly leaving security holes open but not going the jquery route
You can append to an element using innerHTML, just use += instead:
myContentHolder.innerHTML += “This is the dynamic content created by the innerHTML property”;
Then this paragraph will be appended to the end of the content element.
@Stacey:
Thank you for pointing that out. I’ve corrected the error. That’s definitely not a method I’ve personally used too often, so it’s good to know that this property is even more useful than I thought!
Great article!
I was thinking of integrate this article with jquery techniques and with other dom methods and techniques.
Can I do it? Please, can I translate part of this article in italian?
I ask you this because I don’t find any information about license (eg. creative commons).
Congratulations on your blog!!!
@Giacomo:
Sure, go ahead, as long as you provide a link back to my original article.
Thanks.
I just write the article. It is the first part that concerns selection and traversing tecniques. Particularly, I talk about problems with the children property and its solution with childNode. It is in italian language.
Thanks again!
Looks good!
Of course, I don’t know how to read Italian, so what do I know? :o)
Good read, I know jQuery pretty well and I was thinking about learning javaScript.
Very Good Article…….
Please explain getElementsByClassname along with example.
in this tutorials, there is not any explain about classnames methods.
In document.forms how element is converted into array
var radioButtonGroup = document.forms["my_form"]["options"];
Thanks. While I do whitelist most of the useful sites that I visit regularly, I don’t pay attention to the one’s that I open using google search. Thanks for the reminder. Hope others follow your suit. I wish ABP would have some mechanism to see which websites are most regularly white listed and would automatically whitelist them.
I am tryn to html code an app dat calculates for example, d area of a triangle, struggln wt d buttn javascript to display results via a function