Read, With the Name of Your Lord Who Created

When Spaces Does Matter

Posted by triaslama on March 12, 2008

In this post I just want to talk about spaces, why spaces? Because it could be a matter especially when working with DOM (Document Object Model). Look at the following HTML code:

<html>
<head>
<title>Test Spaces</title>
<script lang=”javascript” type=”text/javascript”>
var ul;
var children;
window.onload = function()
{
ul = document.getElementsByTagName(“ul”)[0];
children = ul.childNodes;
};
document.onclick = function()
{
window.alert(“The number of ul’s children: “+children.length);
};
</script>
</head>
<body>
<ul>
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
</ul>
</body>
</html>

Now guess, when I run the code and click the document how many child belongs to ul in the code above? The answer may vary, if you run the code in Firefox 2 or Opera 9.01 browser the answer is 7, but in Internet Explorer 6 (IE6) the answer is 3! Why does it differ? The difference of answers because of spaces!

As you’ll notice, between <ul> and first <li> element there is actually an end line which is considered as a white space. Also between first <li> and second <li>, between second <li> and third <li>, and the last between third <li> and close tag </ul> there is exist end line which considered as white spaces.

White spaces become a matter because its representation in XML. Either Firefox or Opera represent a white space as a node but not in IE. So when we run the code in Firefox or Opera <li> element has 7 childs (four white spaces and three <li> elements).

So far I found two solutions toward spaces problem. First we can skip it, so we need to change document.onclick function into the following:

document.onclick = function()
{
var temp = 0;
for (var i=0;i<children.length;i++) {
if (children[i].nodeType == 1) {
// do some interesting stuffs here…
temp += 1;
}
}
window.alert(“The number of ul’s children: “+temp);
};

Second we can remove it, so change the script into the following:

var ul;
var children;
window.onload = function()
{
ul = document.getElementsByTagName(“ul”)[0];
removeSpaces(ul);
children = ul.childNodes;
};
function removeSpaces(elm)
{
for (var i=0;i<elm.childNodes.length;i++) {
var child = elm.childNodes[i];
if (child.nodeType==3 && /\s/.test(child.nodeValue))
child.parentNode.removeChild(child);
}
}
document.onclick = function()
{
window.alert(“The number of ul’s children: “+children.length);
};

Note: the code above only removes spaces at its current child element, so if <li> element has a child node another than text node, the spaces problem will still remain. We can skip it using first solution although it may impractical especially when our document tree quite large. The better solution I think using a recursive function that traverses the document tree and removes all spaces in document.

Here I listed the nodeType property number and its corresponding type that I used in the preceding code:

nodeType Number

Type

1

Element

2

Attribute

3

Text

4

CDATA Section

5

Entity Reference

6

Entity

7

Processing Instruction

8

Comments

9

Document

10

Document Type

11

Document Fragment

12

Notation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: