Page is a not externally linkable
- Code, Content, and Presentation
-- JavaScript and AJAX
---- How to Master JavaScript


Fotiman - 3:11 pm on Oct 22, 2010 (gmt 0)


I think I can explain. :)

Lets step through it.

First, lets look at the add_element function:

function add_element(parentId, newElementId){
document.getElementById(parentId).innerHTML += '<div id="'+ newElementId +'" class="newElement"></div>';


Lets break that down into smaller chunks for debugging. Here's essentially what you're doing:

var parentEl = document.getElementById(parentId);
var currentInnerHTML = parentEl.innerHTML;
var innerHTMLtoAppend = '<div id="'+ newElementId +'" class="newElement"></div>';
parentEl.innerHTML = currentInnerHTML + innerHTMLtoAppend;


The first time through the loop the values will be:

currentInnerHTML = ''
innerHTMLtoAppend = '<div id="element_1" class="newElement"></div>'

Now lets continue on...


var div = document.getElementById(newElementId);
div.foo = "bar";
div.innerHTML = 'This is '+ div.id +', this.foo = '+ div.foo; //accessing div.foo here works fine
}


So you're getting the element, and then you're adding a DOM property foo (using the syntax div.foo = "..."). This is not the same thing as modifying the HTML of the element. So now the next time through the loop, you end up with this:

currentInnerHTML = '<div id="element_1" class="newElement"></div>'
innerHTMLtoAppend = '<div id="element_2" class="newElement"></div>'

Note, there is no 'foo' attribute in that HTML, therefore when you do this:

parentEl.innerHTML = currentInnerHTML + innerHTMLtoAppend;

You are replacing the current HTML (which DOES contain an HTML element that has a 'foo' property in the DOM), with the innerHTML form of that same element but which does NOT contain a 'foo' property.

So here is another solution (using innerHTML) that works:

function add_element(parentId, newElementId){
var currentHtml = document.getElementById(parentId).innerHTML;
document.getElementById(parentId).innerHTML += '<div id="'+ newElementId +'" class="newElement" foo="bar"></div>';
var div = document.getElementById(newElementId);
//div.innerHTML = 'This is '+ div.id +', this.foo = '+ div.foo; //accessing div.foo here works fine
div.innerHTML = 'This is '+ div.id +', this.foo = '+ div.getAttribute("foo"); //accessing div.foo here works fine
}


Notice that I've changed how we get the value? Instead of getting it via a DOM property (div.foo), I'm getting it via it's HTML attribute (div.getAttribute("foo")). Because this is extending the attributes to include a "foo" attribute, the DOM does not contain a "foo" property, as opposed to the id attribute for example, which has a DOM property on an HTMLElement. This also means that we'll need to change how we access it in the findObjectProperty method:


function findObjectProperty(objectId, propertyName){
var el = document.getElementById(objectId);
alert(objectId +'.'+ propertyName +' = '+ el.getAttribute(propertyName));
}


The reason div.foo worked for the last item was because you added the property after the last innerHTML replacement.

Here is the working version in its entirety :)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Some Title</title>
<script type="text/javascript">
function findObjectProperty(objectId, propertyName){
var el = document.getElementById(objectId);
alert(objectId +'.'+ propertyName +' = '+ el.getAttribute(propertyName));
}
function add_element(parentId, newElementId){
var currentHtml = document.getElementById(parentId).innerHTML;
document.getElementById(parentId).innerHTML += '<div id="'+ newElementId +'" class="newElement" foo="bar"></div>';
var div = document.getElementById(newElementId);
div.innerHTML = 'This is '+ div.id +', this.foo = '+ div.getAttribute("foo"); //accessing div.foo here works fine
}
window.onload = function(){
add_element("container", 'element_1');
add_element("container", 'element_2');
add_element("container", 'element_3');
add_element("container", 'element_4');
findObjectProperty('element_1', 'foo'); //"undefined"
findObjectProperty('element_2', 'foo'); //"undefined"
findObjectProperty('element_3', 'foo'); //"undefined"
findObjectProperty('element_4', 'foo'); //"bar"
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>


Thread source:: http://www.webmasterworld.com/javascript/4216573.htm
Brought to you by WebmasterWorld: http://www.webmasterworld.com