Dynamic Content with DOM-2 (Part I of II)
Pages: 1, 2, 3
More Node Manipulations
You can remove existing nodes as well as add new ones. The removeChild method allows any node to remove one of its child nodes. Simply pass a reference to the node you wish to remove. Any text or elements within the node being removed will be removed along with it.
The text between these bold tags will disappear when the B element is removed from the paragraph.
<script type="text/javascript">
function removeBElm(){
var para = document.getElementById("example2");
var boldElm = document.getElementById("example2B");
var removed = para.removeChild(boldElm);
}
</script>
Nodes that are removed are not destroyed. removeChild returns a reference to the node that was removed so additional manipulations can be made with it later. In the example above, notice that we've assigned the removed B element to the removed variable, thus maintaining a reference to it.
Depending on the browser implementation, you may get errors if you try to remove a non-existent node or one that has been marked as read-only.
Replacing Nodes
In addition to removing nodes, the DOM offers a way to replace one node with another. The replaceChild method accomplishes this. As with removeChild above, replaceChild needs to be called from the element that contains the node you wish to replace.
replaceChild takes two arguments: a reference to the new node, and another to the node being replaced. The following example creates a new SPAN element containing a text node, and uses it to replace an existing SPAN.
<script type="text/javascript">
function replaceSpan(){
var newSpan = document.createElement("span");
var newText = document.createTextNode("on top of the astounded zebra");
newSpan.appendChild(newText);
var para = document.getElementById("example3");
var spanElm = document.getElementById("ex3Span");
var replaced = para.replaceChild(newSpan,spanElm);
}
</script>
You can try this example here:
The quick brown fox jumps over the lazy dog.
Inserting Nodes in a Sequence
You may have noticed in the previous examples that appendChild always places the newly appended node as the very last child of the parent node. There are times when it is desirable to insert a node before or in-between existing child nodes.
The insertBefore node method provides a way of accomplishing this. insertBefore takes two arguments: the new node to insert and the node you wish to have prepended. The following example uses insertBefore to insert a new TD element before the third existing TD in an HTML table.
var newTD = document.createElement("td");
var newText = document.createTextNode("New Cell " + (TDCount++));
newTD.appendChild(newText);
var trElm = document.getElementById("example4");
var refTD = trElm.getElementsByTagName("td").item(2);
trElm.insertBefore(newTD,refTD);
}
</script>
You can try this example here:
TD One
TD Two
TD Three
The Road Ahead
We've covered how DOM-2 makes generating on-the-fly HTML and manipulating page elements extremely simple, but you may be looking for more power. This article doesn't cover how to affect attributes of elements, like table cell widths, background colors, and so forth. In the next article, you'll see how DOM-2 can be used to manipulate the attributes of elements and create dynamic effects. You will also see some additional methods and properties of the node and element interfaces that provide easier references to objects in the DOM tree.
Scott Andrew LePera
lives in San Francisco, where he ekes out a schizoid existence as both a web applications developer for KnowNow and a frustrated urban folk singer.
The quick brown fox...
2005-04-27 12:42:27
normalforce
[View]
I have noticed something interesting. When I click on the "call replaceSpan()" button the first time and have the fox jump ontop of the astounded zebra I don't get any Javascript errors. However, the next time I click on it, I get an uncaught exception error on the line that with the replaceChild method.
This is the same problem I have when I have two buttons trying to make the fox do different things. The first button successful writes the text while the second yields the aforementioned error.
Am I missing something? Should the variables be cleared before trying to write another textNode to the span? I can't figure out what I am doing wrong.
The quick brown fox...
2005-04-27 13:16:48
normalforce
[View]
Don't you just love it when you post a question and then figure it out through a random chain of events about 5 minutes later...
The problem was, after changing the content the first time, the newSpan was never assigned a value of the old id. Thus when you run the function again,
var spanElm = document.getElementById("ex3Span");
returns a null because ex3Span doesn't exist anymore. To get around that, just assign newSpan the old id, as so:
I am curious about multiple replacements
2003-08-28 12:12:16
anonymous2
[View]
This was an amazingly helpful article. Thanks for it. I have been playing around with the replace script, I am wondering if there is a way to replace text (or any node) a number of times. Like if I want three pages of text that replace on an onClick event.
thanks.
i am trying to insert an inputfield into my cell. but it don't work with createTextNode, andt I cant find a solution with innerHTML either.
Does anybody have a solution?
Inserting Nodes without pre-existing table
2002-04-29 18:32:44
madmiarde
[View]
Your article was great! In stepping through some of your examples, specifically the "Inserting Nodes in a Sequence" portion, I can't figure out how you would do it if the table didn't exist already. Your example started with a table, row and three data cells. I can duplicate this without problem. When I try to start with an empty table, it will not work. Here's what I start with:
<table id="table1">
</table>
I then try to create a new row and add a cell to it with this:
//get reference to the table on the form
var t1 = document.getElementById( "table1" );
//create a row
var tr1 = document.createElement( "tr" );
tr1.setAttribute( "id", "tr1" );
t1.appendChild( tr1 );
//create cell
var td1 = document.createElement( "td" );
var td1Text = document.createTextNode( "cell text" );
td1.appendChild( td1Text );
tr1.appendChild( td1 );
I even tried getting another reference to the row and using it instead of the existing reference(tr1):
var tr1Ref = document.getElementById("tr1");
tr1Ref.appendChild(td1);
But I had no luck. I even tried splitting the row and cell into different fucntions but still nothing (just humoring myself). Any ideas? Is it possible?
Thanks again for the great article! Running IE5.5 on WinME.
Inserting Nodes without pre-existing table
2002-06-13 07:13:38
iq_soft
[View]
The point is also to create TBODY element
within your table. Try this:
<table>
<tbody id="table1">
</tbody>
</table>
and the rest of your code should work....
at least it works for me (IE, NS, Mozilla)
Inserting Nodes without pre-existing table
2002-06-14 12:53:19
madmiarde
[View]
Thanks for the reply! You were correct - the only thing I was missing was the tbody element. I found it in an article on Microsoft's site.
Most of the books out there, even from O'reilly, simply do not cover foundation material for W3C ID DOM. I bought many books and was very disapointed, as most covered older NS4 and sometimes only IE5. I scoured the net for resources, but found that many scripts were (1) not even JavaScripts but CSS... (2) would only work for either IE4 or NS4, or (3) is cross-browser meaning only NS4 and IE4/5. I found some useful stuff at Netscape and Mozilla, but nothing could really tell me how it was done before, and how it is done in ID DOM.
I find this and other articles here, extremely helpful. This combined with other fragmented information will show me how to create truly cross-browser code, and also base most of my code on progamming W3C...
I don't think the changes are supposed to be changed it's more a way to make a page interactive without the need to bog down the server with requests. A good example of what this can be used for is to create dynamic forms so that you can let the user choose how many entries he/she wants to do instead of forcing the user to make one entry at a time and them press the submit button.
This is the same problem I have when I have two buttons trying to make the fox do different things. The first button successful writes the text while the second yields the aforementioned error.
Am I missing something? Should the variables be cleared before trying to write another textNode to the span? I can't figure out what I am doing wrong.