...

View Full Version : appendChild not appending child properly



VIPStephan
05-13-2008, 12:27 AM
I have a definition list and was gonna make the items display in a line with an equal sign between each related definition term and desciption pair:


<div id="info">
<h2>&ldquo;Animals&rdquo;</h2>
<div>
<h3>Key</h3>
<dl>
<dt>RF</dt>
<dd>Royalty Free</dd>
<dt>RM</dt>
<dd>Rights Managed</dd>
<dt>P</dt>
<dd>Suitable for print use</dd>
<dt>W</dt>
<dd>Suitable for web use</dd>
</dl>
</div>



It’s supposed to look like:


RF = Royalty Free RM = Rights Managed P = Suitable for print use W = Suitable for web use

It all works nicely with the :after CSS pseudo class but as the experienced web developers will know this ain’t workin’ in IE for which I wanted to resort to JS. No big thing so far but for some reason that I can’t figure out my for loop isn’t applying the text node to all items, only to the last one:



function nodes() {
if(getEl('info')) {
var colon = document.createTextNode(':');
getEl('info').getElementsByTagName('h3')[0].appendChild(colon);

var equal = document.createTextNode(' = ');
var dt = getEl('info').getElementsByTagName('dt');
for(i=0; i<dt.length; i++) {
dt[i].appendChild(equal);
}
}
}


getEl() is a shortcut function for document.getElementById() by the way.

What did I do wrong and how to correct it?

liorean
05-13-2008, 12:56 AM
It all works nicely with the :after CSS pseudo class but as the experienced web developers will know this ain’t workin’ in IE for which I wanted to resort to JS. No big thing so far but for some reason that I can’t figure out my for loop isn’t applying the text node to all items, only to the last one:Actually it's appending it to each of them, but since you are appending *the same* node, it has to be removed from it's present parent in order to be given a new parent, each iteration through the loop.
What did I do wrong and how to correct it?Clone it each time through the loop.

oesxyl
05-13-2008, 01:07 AM
function nodes() {
if(getEl('info')) {
var colon = document.createTextNode(':');
getEl('info').getElementsByTagName('h3')[0].appendChild(colon);

var equal = document.createTextNode(' = ');
var dt = getEl('info').getElementsByTagName('dt');
for(i=0; i<dt.length; i++) {
dt[i].appendChild(equal);
}
}
}


getEl() is a shortcut function for document.getElementById() by the way.

What did I do wrong and how to correct it?

appendChild:

http://www.javascriptkit.com/domref/elementmethods.shtml



Inserts the specified node at the end of the current node object. A frequently used method for dynamically appending a new element or text to the document


I thing that you must use replaceChild(newChild, oldChild) after you get the content of the old node and concatenate '='.

Sorry, I have a little experience with js with dom therefor I don't provide some code. But I'm sure you don't need, :)

regards

Arbitrator
05-13-2008, 05:31 AM
[Ö] how to correct it?

Solution 1
This involves creating a new text node on each loop iteration. This is the method that I prefer, personally.


var d = document;
function nodes() {
if(getEl("info")) {
getEl("info').getElementsByTagName("h3").item(0).appendChild(d.createTextNode(":"));
for (var i = 0; i < dt.length; i++) {
getEl("info").getElementsByTagName("dt").item(i).appendChild(d.createTextNode(" = "));
}
}
}

Solution 2
This involves cloning an existing node on each loop iteration as liorean proposed.


var d = document;
function nodes() {
if(getEl("info")) {
getEl("info').getElementsByTagName("h3").item(0).appendChild(d.createTextNode(":"));
var equal = d.createTextNode(" = ");
for (var i = 0; i < dt.length; i++) {
getEl("info").getElementsByTagName("dt").appendChild(equal.cloneNode(false));
}
}
}

Solution 3
This involves concatenating the new text with the existing text of a text node. No new nodes need to be created. Note that this code will only work if the last node in the dt element is a text node. This solution is a simplified version of what oesxyl proposed doing.


var d = document;
function nodes() {
if(getEl("info")) {
getEl("info').getElementsByTagName("h3").item(0).appendChild(d.createTextNode(":"));
for (var i = 0; i < dt.length; i++) {
getEl("info").getElementsByTagName("dt").item(i).lastChild.data += " = ";
}
}
}

Kor
05-13-2008, 11:06 AM
Do I miss something, or you may simply concatenate the textNode value?:


function nodes() {
if(e=getEl('info')) {
e.getElementsByTagName('h3')[0].firstChild.nodeValue+=':';
var dt = e.getElementsByTagName('dt'), i=0, d;
while(d=dt[i++]){
d.firstChild.nodeValue+=' = ';
}
}
}

VIPStephan
05-13-2008, 08:13 PM
Awesome! Thank you guys… I learn something new every day. :)

I went with Arbitrator’s solution 1 as it appeared most easily understandable by me and it’s actually so simple that I should have thought of that way myself. :rolleyes:

Arbitrator
05-15-2008, 06:28 AM
Do I miss something, or you may simply concatenate the textNode value?Yeah, I did that in Solution 3. I believe that your way is more efficient, but itís also more confusing IMO.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum