on Thu Aug 21 12:44:07 GMT 2008 in Javascript and viewed 10131 times
The third and final part to starting to manipulate the Document Object Model with Javascript. This covers using the innerHTML property, creating nodes, and deleting nodes.
The last and final installation to this trilogy of a tree, will involve directly influencing the Document Object Model, metaphorically playing God with the DOM tree, creating and destroying nodes inside the DOM tree using createElement, createTextNode, removeChild, appendChild, and insertBefore. We’ll also cover the innerHTML property.
So to quickly start here, let’s think of what real-world application we could have here. How about one of those cool interactive forms we always see. Where selecting something from a drop down list immediately adds an info box.
<html>
<head><title>DOM equals greatness</title>
<script type="text/javascript">
function displayInfo(whatinfo){
var info = document.createElement("p");
document.body.appendChild(info);
switch(whatinfo){
case "attributes":
var text = "You have getAttribute and setAttribute. getAttribute takes one argument, setAttribute takes two.";
break;
case "tree":
var text = "There are two functions: getElementsByTagName, which returns an array, and getElementById, which returns a single element based on the id attribute.";
break;
case "god":
var text = "There are many functions. createElement, appendChild, insertBefore, createTextNode, and removeChild.";
break;
}
info.innerHTML = text;
}
</script></head><body>
<form action="formaction" method="post">
Methods in the DOM: <select name="selection">
<option value="attributes" onclick="displayInfo(this.value)">Attributes</option>
<option value="tree" onclick="displayInfo(this.value)">Traversing the Tree</option>
<option value="god" onclick="displayInfo(this.value)">Creating and destroying nodes</option>
</select>
</form>
</body></html>
Notice it’s a bit crass, not anything refined at the moment, we’ll build up to that. First things first, we have a pointless form. the action and method didn’t really matter. Then the selection element, pretty basic. Now the options are where we have some magic. They each have the onclick attribute which will invoke the displayInfo() function with the argument of their value which one is selected. Pretty easy.
The script is also very straightforward. When you create an element using document.createElement(“elementtype”), it’s stuck in a sort of limbo area. It can’t actually be seen until it’s inserted into the document using either insertBefore, or appendChild. We’ll use the function appendChild just for now. We could just as easily have used insertBefore, but I wanted the info to appear after the list.
Next it’s just a simple matter of a switch statement to set the text to be what you want. The innerHTML property of any element is like carefully trying to pound a tiny nail into the wall with a sledgehammer. You’re effectively destroying any text within the element before. You can also return all the HTML within the item. Instead of returning text as you usually would with a text node’s value, it would return everything as a string, even HTML elements, like “Hello, I <em>love</em> Javascript”, as opposed to “Hello, I ” like a text node’s value would be.
Anyways, I’m getting off track. The annoying part of this script is that I can create new paragraphs, even if the paragraphs I created already existed. So we can easily solve this by using the removeNode ability. Also, instead of using innerHTML, let’s say you wanted to create a text node instead using createTextNode. Note that createTextNode behaves like createElement: they both are suspended in a “limbo” until they are assigned to a parent.
So here is our updated script.
function displayInfo(whatinfo){
if(test = document.getElementById("paragraph")) {
document.body.removeChild(test);
}
var info = document.createElement("p");
info.setAttribute("id", "paragraph");
switch(whatinfo){
case "attributes":
var text = document.createTextNode("You have getAttribute and setAttribute. getAttribute takes one argument, setAttribute takes two.");
break;
case "tree":
var text = document.createTextNode("There are two functions: getElementsByTagName, which returns an array, and getElementById, which returns a single element based on the id attribute.");
break;
case "god":
var text = document.createTextNode("There are many functions. createElement, appendChild, insertBefore, createTextNode, and removeChild.");
break;
}
info.appendChild(text);
document.body.appendChild(info);
}
Now the first thing I added was to see if you could find an element with the id paragraph and assign it to the variable test. If so, we had to remove it, just to keep things clean. The next thing was normal, to create the element. Then I set the new id attribute to paragraph. Also notice that I don’t add the info element until the very end. This is just for some readability. The switch statement hasn’t changed, except now instead of making the variable text a string, I assigned a new text node to it. The function for createTextNode takes one argument: a string. Then at the end, I added the text node to the info element, and finally added the info element into the tree.
So now if you test it, it works flawlessly. It’ll insert a paragraph, then take it out and insert a new one. We could style these easy using CSS, since the id attribute is set on it. Easy to style, easy to use, makes for a great user experience.
The first example that you presented in this page is not working in Internet Explorer whic is used by many of the people. But it is being executed in Mozilla. Hope this error can be cleared soon.
by Krishna Kishore