In this tutorial you will learn about nodes and their place in javascript. More specifically the basics (childNodes, parentNode, firstChild, lastChild, nextSibling, previousSibling, nodeName, nodeType, text nodes, createTextNode, nodeValue).
Take a look at the below HTML document.
<html>
<body>
<font>
Text
</font>
</body>
</html>Nodes are basically html tags. The first thing you'll want to do is grab the node/tag.
var nBody=document.getElementsByTagName('body')[0];I used 0 assuming that it's the first "body" tag in the document. Once you've done that, the following will become true.
nBody.parentNode = html
nBody.firstChild = font
Now then, a parentNode is whatever tag encloses the other. Since the html tag encloses the body tag, the html tag is it's parent. This is not true for the font tag. The font tag is enclosed by the "body" tag. Making
it the parent. Let's take another look:
<html>
<body>
text
</body>
</html>What encloses the "body" tag? The "html" tag, correct? That makes the "html" tag the
parent of the "body" tag. It also makes the "body" tag the
child of the "html" tag. Get it?
<table>
<tbody>
<tr id="tr1">
<td id="td1">
text
</td>
</tr>
<tr id="tr2">
<td id="td2">
text
</td>
</tr>
</tbody>
</table>We are going to grab the table.
var nTable=document.getElementsByTagName('table');Once we've done that what will the table's parent be? Nothing. Because no tag encloses it. What will it's child be? "tbody". "tbody" has children of it's own. The "tr" tags to be precise. The "tr" tags have
their own children as well. Being the "td" tags. Take a look at this chart:
nTable.parentNode = null
nTable.firstChild = tbody
nTable.firstChild.firstChild = tr (id=tr1)
nTable.firstChild.lastChild = tr (id=tr2)
nTable.firstChild.firstChild.firstChild = td (id=td1)
nTable.firstChild.lastChild.firstChild = td (id=td1)
The firstChild attribute identifies the first child of the parent. The last child attribute identifies the last child of the parent. The table's first and only child was "tbody". "tbody" has children as well. We used "firstChild" to grab "tbody" and then firstChild again to grab "tbody's" first child (tr id=tr1). So, we grabbed the first child of the first child. Meaning we grabbed "table's" first child (tbody) and "tbody's" first child (tr id=tr1). By using firstChild 3 times, we grab tbody, then tr, then td (id=td1). By using firstChild.lastChild, we grab tbody, then "tbody's" last child (tr id=tr2) we could then use firstChild to grab the first child of that tr.
Kind of confusing eh? Let's go through a couple more examples:
<html id="grandpa">
<body id="father">
<font id="child">
hello
</font>
</body>
</html>Think of it this way, html is the grandfather, body is the father, font is the child. Who is the parent of the father (body)? The grandfather (html). Who is the son of the grandfather? The father (body). Who is the child of the father (body)? The child (font).
Get it? And by using firstChild.firstChild on the grandfather, we grab the child of the grandfather, then the child of the father.
Easy.
<html id="grandfather">
<body id="father">
<font id="child1">
text
</font>
<font id="child2">
text
</font>
</body>
</html>So, who is the parent of the father (body)? The grandfather (html). Who is the firstChild of the father (body)? child1 (font id=child1). Who is the lastChild of the father (body)? child2 (font id=child2). You could also use the nextSibling object. Example:
nBody.firstChild.nextSiblingThat will grab the father's first child (font id=child1) and then grab the nextSibling of that child (font id=child2).
If there's a "nextSibling", there must be a "previousSibling", right? Yes, there is. It works just like "nextSibling" so I doubt I need to go over it. There's one more way to do this:
nBody.childNodes[1]Remember, javascript starts counting at 0. The above method will grab the secong child of the father.
nBody.childNodes[0] would grab the first child.
So, we've covered firstChild, lastChild, childNodes, nextSibling, and parentNode. What's next?
Let's say you want to grab a particular tag, but don't know where it is. You can use the nodeName property.
<html>
<body>
</body>
</html>In this example we are going to grab the body of the html document (
document.body). Now we will use the parentNode property to grab the parent of the body tag (
document.body.parentNode). Let's say for a moment that we don't know what it's parent is. We can use nodeName to check (
document.body.parentNode.nodeName). What will it return? It will return the name of the body tag's parent (HTML).
There are also ways to check what
type the node we've grabbed is. You can check for either "element" or "text" using the nodeType property. It will return 1 if the node is an html element and 3 if it is a text node. Example below:
<html>
<body>
blah blah
</body>
</html>First we will grab a tag. I'll again grab the body (
document.body). I will then use the nodeType property to check and see if the node is a text node or an element (
document.body.nodeType). This is kind of pointless since we already know our body tag is an element but what will it return? It will return 1 because, as we've noted, the node we've grabbed is an element. Let's take a look at a slightly more
useful example of the nodeType property.
<html>
<body>
<font>
blah blah
</font>
</body>
</html>This time i'll grab the font tag from the document (
document.getElementsByTagName('font')[0]). I'm using [0] because it's the first font tag in the document. Now then, I will use firstChild to identify the first child of the font tag (
document.getElementsByTagName('font')[0].firstChild). As you can see, the font tag encloses text. This text is identified as a text node (which I will cover later on). We've established that if the nodeType property returns "1", the node is an element. And if it returns "3", the node is a text node. Now then, we've grabbed the firstChild of our font tag. We will then use nodeType to identify what
type of node it is (
document.getElementsByTagName('font')[0].firstChild.nodeType). Let's fit this snippet into an alert.
<script>
alert(document.getElementsByTagName('font')[0].firstChild.nodeType);
</script>What will this alert return? Is the firstChild of the font tag in the previous document a text node or an element? It's a text node. So the alert will return "3".
Now then, what
are text nodes? Well, you are familiar with nodes as being elements. But those elements often contain text. The text is referred to as a text node. Keep in mind that text nodes, like elements, hold their own values. If you are familiar with the createElement object, you may be wondering if there's a way to create
text nodes as well. As a matter of fact, there is. It's called createTextNode.
<html>
<body>
</body>
</html>hmm...Our body tag has no text. Why don't we create a text node and "append" it to the body?
<script>
var nContent=document.createTextNode('The text of the body element');
</script>Here we've created our text node. It has a text value of "The text of the body element". Keep in mind that tags cannot be used here. It is a
text node and text nodes are contained
within html elements. So, we've created our textNode, what do we do with it? We'll append it to the document using another property known as "appendChild" (don't worry about how it works, i'll cover it later in the tutorial).
<script>
var nContent=document.createTextNode('The text of the body element');
document.body.appendChild(nContent);
</script>Next in line, nodeValue. The nodeValue property is used to identify the text nodes of an html element. It's somewhat like "innerHTML". If the value of the element is another element, nodeValue returns "null".
<html>
<body>
<font>
blah blah
</font>
</html>In this example I will be addressing the font tag and it's nodeValue. First I need to grab the tag (
document.getElementsByTagName('font')[0]). Remember when I said that text nodes hold their own values, well, we must first grab the text node. We can do this by using firstChild (
document.getElementsByTagName('font')[0].firstChild). Now that we've addressed our text node, we can use the nodeValue property to identify it's value (
document.getElementsByTagName('font')[0].firstChild.nodeValue). Ok, so we've addressed it's node value, what should we do with it?
<script>
alert(document.getElementsByTagName('font')[0].firstChild.nodeValue);
</script>Why not use another alert?
What will the alert return? Well, we grabbed the font tag, then it's text node followed by the value of that text node. The alert will return "blah blah" as it is the value of the addressed text node.
Last but not least, appendChild. This particular property is used to append nodes to html elements. Take a look at the below document.
<html>
<body>
<font>
</font>
</body>
</html>What good is a font tag when there's nothing in it? Let's create a text node and append it to the font tag.
<script>
var nContent=document.createTextNode('hello');
</script>Ok, so we've created our text node. Now we need to address the font tag.
<script>
var nContent=document.createTextNode('hello');
document.getElementsByTagName('font')[0];
</script>Now let's append our text node to the font tag using appendChild.
<script>
var nContent=document.createTextNode('hello');
document.getElementsByTagName('font')[0].appendChild(nContent);
</script>Simple as that. Now, you may be wondering, why is it append
Child? Well, to append something you must have something to append it to. Meaning it will always be a child of some element.