Skip to content
Aasim's Web Corner
Aasim's Web Corner

Ink is better than the best memory.

  • Odysseys & Artistry
    • Saunterer Soul
    • My Poetry
    • My Sketch Work
  • Project Management
    • Agile & Frameworks
    • PMP Certification
  • Digital Diary
    • History
    • Islam
    • Life Around Us
    • My Bookshelf
  • My Tutorials
    • Amazon Kindle
    • Android
    • Aspect Oriented Programming
    • BlackBerry
    • Code Repositories
    • iOS
    • Java
    • JavaScript
    • Linux
    • Random Tips
Connect with me
Aasim's Web Corner

Ink is better than the best memory.

JavaScript-AasimNaseem.com

Document Object Model :: JavaScript Tutorial

Aasim Naseem, June 30, 2010 | Read Count: 15,435April 30, 2025
Category: My Tutorials > JavaScript

Hello All …

Hope everything is going good at your end …

today we will explore something about Document Object Model (DOM). From last few days i’m working on javascript and hence i read some good articles about script and dom…i learned alot and now sharing with you …

Introduction

The Document Object Model (DOM) is an application programming interface (API) for valid HTML and well-formed XML documents. It defines the logical structure of documents and the way a document is accessed and manipulated.

With the Document Object Model, programmers can build documents, navigate their structure, and add, modify, or delete elements and content. Anything found in an HTML or XML document can be accessed, changed, deleted, or added using the Document Object Model, with a few exceptions

The DOM is a programming API for documents. It is based on an object structure that closely resembles the structure of the documents it models. For instance, consider this table, taken from an HTML document:

<TABLE> <TBODY> <TR> <TD>Shady Grove</TD> <TD>Aeolian</TD> </TR> <TR> <TD>Over the River Charlie</TD> <TD>Dorian</TD> </TR> </TBODY> </TABLE>

graphical representation of the DOM of the example table

What is DOM Tree

Consider the following code snippet of HTML taken from a regular HTML document.

&lt;title="The test paragraph"&gt;
This is a sample of some &amp;lt;b&amp;gt;HTML you might&amp;lt;br&amp;gt;have&amp;lt;/b&amp;gt; in your document&amp;lt;/p&amp;gt;

In your browser, this renders as this (hold your mouse over the paragraph to see the title – most browsers display it as a tooltip, some display it in the status bar):

This is a sample of some HTML you might
have
in your document

The DOM tree views this (simplified) as follows:

                                              P
                               _______________|______________
                              |                              |
                          childNodes                    attributes
                ______________|___________                   |
               |              |           |            title = 'The test paragraph'
'This is a sample of some '   B   ' in your document'
                              |
                          childNodes
                    __________|_______
                   |          |       |
           'HTML you might'   BR   'have'

Of course, the tree also extends above the ‘P’ from window.document, through the HTML element, down through the body element, then through any other container elements to the paragraph.

The parts of the DOM tree are known as nodes. The ‘P’, ‘B’ and ‘BR’ nodes are element nodes, childNodesand attributes are collections, the title='The test paragraph' pair is an attribute node, and the text strings are text nodes.

Referencing the element nodes

Using the DOM, there are several ways that we could reference the paragraph. We can use getElementsByTagName to reference all paragraphs, then choose the one we want. If the paragraph were to be given an id, we could also use getElementById:

document.getElementById('id of paragraph')
document.getElementsByTagName('p')[indexOfParagraph]

If we assigned the paragraph an id so that we could use getElementById, the id='elementID' pair would appear in the attributes collection, along side title='The test paragraph' in the tree diagram above. Note that if the document is served with an XML based content-type header, getElementsByTagNamebecomes case sensitive.

NOTE: getElementsByTagName does not return a true collection, it returns an object with element index and ‘length’ properties. This object keeps itself up to date, so if an element it references is deleted or added, it will automatically change its item references to reflect that change.

We could even walk the entire DOM tree from the document object, for example:

window.document.childNodes[0].childNodes[1].childNodes[4]

In this case, window.document.childNodes[0] should be the HTML element, as it is the first tag in the document (assuming there is no doctype tag), and window.document.childNodes[0].childNodes[1]should be the body tag, as the head element will be the first child of the HTML element. Alternatively, there is a shortcut to the HTML element: document.documentElement so we could use this:

window.document.documentElement.childNodes[1].childNodes[4]

There is also a shortcut to the BODY element: document.body so we could use this:

window.document.body.childNodes[4]

Those last three examples are based on a simple page structure, where the paragraph is a direct child of the body element. Neither of these would be correct in the current document as the document structure is far more complex, also using DIV elements as parents of the paragraph.

The techniques used in those examples can be unreliable. Most browsers will correctly view the blank space between tags as a text node containing only white space characters (such as space, line-break or tab), even if the blank space is not rendered, such as a gap in between a tag or a blank gap in betweentags. However, some browsers (mainly Internet Explorer) will not view this empty space as a text node at all.

This means that the childNodes collection will be different lengths in these different browsers. If you are trying to walk the DOM tree to the next element node, for example, it may be worth checking each entry in the childNodes collection to see if its nodeType is 1, or to use node.getElementsByTagName.

Because of this, and the fact that the structure of the DOM tree is designed to change as elements are moved, added or removed, the only reliable way to reference an element is using its ID:

var theParagraph = document.getElementById('id of element')

The first entry of the childNodes collection can be accessed using the shortcut firstChild, and the last can be accessed using lastChild. node.nextSibling references the next entry in the parent node’s childNodes collection and node.previousSibling references the previous one. To reference the parent node, we use node.parentNode. Note also that all element nodes have the getElementsByTagName method to help reference elements within them. This means that from any node, it is possible to reference any of the other notes around it.

Referencing the attribute node

To reference the title=’The test paragraph’ attribute pair, we use the attributes collection. Depending on the browser, this collection may be filled up in a variety of different ways, and many empty attribute pairs may exist in the collection. To find the correct attribute, we search through the attributes collection for an attribute whose nodeName matches what we want. The nodeName may be in any case in HTML documents (typically upper case) and should be case sensitive in XHTML and XML if served using an XML based MIME type.

for( var x = 0; x < theParagraph.attributes.length; x++ ) {
  if( theParagraph.attributes[x].nodeName.toLowerCase() == 'title' ) {
    window.alert( 'The value of the \'title\' attribute is: ' +
      theParagraph.attributes[x].nodeValue );
  }
}

An easy way to check the attribute node

If all you want to do is to check the value of an attribute, not manually edit its entry, it is easier to just use getAttribute.

window.alert( 'The value of the \'title\' attribute is: ' +
  theParagraph.getAttribute('title') );

Attribute names are case sensitive. For example, bgcolor must be written as bgColor.

Note that according to the specification, getAttribute should always return a string. However, this makes it impossible to differentiate between empty attributes and unspecified attributes. For this reason, browsers will return null for unspecified attributes, even though this is wrong. Opera 7-8 returns an empty string – this was changed to null in Opera 9. As a result, code that checks for attributes and incorrectly tests against null will fail in Opera 7 and 8, because a string will never equate to null. There is no need to test against null, just check if get attribute failed to retrieve a value:

if(!element.getAttribute('attribute_name'))

Changing the attribute

The attributes of an element can be set or changed using setAttribute:

element.setAttribute('attributeName','attributeValue')
theParagraph.setAttribute('align','center')

Attribute names are case sensitive. For example, bgcolor must be written as bgColor.
You can also remove attributes, with a few exceptions, using removeAttribute:

theParagraph.removeAttribute('attributeName')

The event handler attributes are available as referenced functions (this is not the case for handlers added using DOM events), with their names matching the attribute name; element.onclick. These are read/write but must be written as a reference to a function, not as a direct string. They can also be written as a string using the Function constructor:

element.onclick = new Function(codeAsAString);

They may also be read as a string using the toString method of the function, but note that it will normally contain the anonymous function wrapper, and may not be available at all in browsers running on devices with limited capabilities, such as mobile phones. Note also that it will not be available at all if the attribute is not present:

var functioncode = element.onclick.toString();

The string value of the style attribute is available as a read/write string called cssText, which is a property of the style object, which itself is a property of the element. Note, however, that it is not supported very well; Safari does not support it up to version 1.1 (reading it produced the value null), Mozilla versions prior to 1.0 could not write to it, and iCab 3-, NetFront and Escape/Evo do not support it at all. To avoid problems with its use, a combination of cssText and getAttribute/setAttribute can be used. To read it:

var cssString;
cssString = element.style.cssText;
if( typeof(cssString) != 'string' ) {
  cssString = element.getAttribute('style');
}

To write it, simply set both versions, and the browser will use whichever one works:

var cssString = 'color:lime;font-weight:bold;';
element.style.cssText = cssString;
element.setAttribute('style',cssString);

Note that this will then prevent it from being read correctly if other styles are changed individually. If this will cause a problem, check if cssText is supported first:

var cssString = 'color:lime;font-weight:bold;';
if( typeof(element.style.cssText) == 'string' ) {
  element.style.cssText = cssString;
}
element.setAttribute('style',cssString); 

Referencing the text nodes

To give a full example, I will try to reference the text node ‘HTML you might’. To do this, I will go through the second entry of the childNodes array of the ‘P’. This will be a reference to the ‘B’. I will then look at the firstChild (equivalent to the first entry in the childNodes collection) of the ‘B’ to reference the text node.

window.alert( 'The value of the text node is:\n' +
  theParagraph.childNodes[1].firstChild.nodeValue );

Also important to note is that although the specifications say that no matter how much text exists between tags, it should all be in one text node, in practice this is not always the case. In Opera 7-9.2x and Mozilla/Netscape 6+, if the text is larger than a specific maximum size, it is split into multiple text nodes. These text nodes will be next to each other in the childNodes collection of the parent element.

In Opera 7-9.2x, this maximum text node size is 32 KB. In Mozilla/Firefox/Netscape 6+, it is 4 KB. Although the normalize() method of the parent node(s) should be able to replace the multiple text nodes with a single text node containing all the text, this only works in Mozilla/Firefox/Netscape 6+. In Opera 7-9.2x it puts all of the text into a single node and then truncates that node to 32 KB, so the contents of all except the first node are lost. Running the normalize method can crash Internet Explorer 6 and does not exist in Internet Explorer 5 on Windows.

For this reason, I do not recommend trying to normalize. It is better to manipulate the contents of text nodes separately. In fact, you can create your own text nodes and add them to the childNodes collection. Although to the DOM, they will still appear as separate nodes, they will appear as a single piece of text in the document. Basically, you need to be aware that your text may be split into several nodes, if it is 4 KB or over, or if you have added extra text nodes in yourself. In order to get that text in a single variable, you may need to look through every child node, and if they are consecutive text nodes append them together to get the total string.

Creating new nodes and removing existing ones

This is what the DOM was truly created for. In order to create new nodes, we use a couple of methods of the document object to create the node. We then insert the node into the main DOM tree, at which point the browser will display it. We can also move existing nodes (like the test paragraph) simply by inserting them into the DOM tree somewhere else.

Note that when creating element nodes, the element name must be in lower case. Although in theory it should not be case sensitive with HTML, I have noticed some problems in Konqueror when using upper case with strict doctypes – see the top of this page. It will be case sensitive with XHTML (in all compliant browsers, not just Konqueror), and must be in lower case.

var theNewParagraph = document.createElement('p');
var theTextOfTheParagraph = document.createTextNode('Some content.');
theNewParagraph.appendChild(theTextOfTheParagraph);
document.getElementById('someElementId').appendChild(theNewParagraph);

We could also use insertBefore instead of appendChild, or even manually add the new element to the end of the end of the childNodes collection. Using replaceChild, we could also overwrite existing nodes. It is also possible to copy a node using cloneNode(true). This returns a copy of the node but does not automatically add it into the childNodes collection. Using element.removeChild(referenceToChildNode), we can remove existing nodes.

How about something even more complicated. What about adding HTML elements within the new element, instead of just plain text. Here, I will recreate the test sentence from above, one piece at a time.

//three elements are required: p, b, br
var theNewParagraph = document.createElement('p');
var theBoldBit = document.createElement('b');
var theBR = document.createElement('br');

//set up theNewParagraph
theNewParagraph.setAttribute('title','The test paragraph');

//prepare the text nodes
var theText1 = document.createTextNode('This is a sample of some ');
var theText2 = document.createTextNode('HTML you might');
var theText3 = document.createTextNode('have');
var theText4 = document.createTextNode(' in your document');

//put together the bold bit
theBoldBit.appendChild(theText2);
theBoldBit.appendChild(theBR);
theBoldBit.appendChild(theText3);

//put together the whole paragraph
theNewParagraph.appendChild(theText1);
theNewParagraph.appendChild(theBoldBit);
theNewParagraph.appendChild(theText4);

//insert it into the document somewhere
document.getElementById('someElementId').appendChild(theNewParagraph);

n case you were wondering how I managed to make those new paragraphs end up just above the links you clicked on, this is how.

The link you clicked on is in a paragraph. The paragraph is in a div (although this technique would work anywhere). The script is run in the event handler for the link. Therefore, in the handler function, ‘this’ refers to the link. The parentNode of the link is the paragraph – this.parentNode – and the parentNode of the paragraph is the div – this.parentNode.parentNode. I want to get the div to import the new paragraph node I have created above the paragraph the link is in, so I want to say this:

theDIV.insertBefore(theNewParagraph,theCurrentParagraph); 

In JavaScript, this would be:

this.parentNode.parentNode.insertBefore(theNewParagraph,this.parentNode); 

As for making them disappear when you click on them, when creating these paragraphs, I also assign an onclick event handler function that uses this.parentNode to reference the div, and then uses removeChild to delete the paragraph:

theNewParagraph.onclick = function () { this.parentNode.removeChild(this); };

Note that nodes belong to the document they were created in. So for example, if your page uses frames, and you create a paragraph node in one frame then attempt to add it to the document in another frame, it will not work. In theory you can use the document.importNode method to create a copy of it in the new document, but that method does not exist in Internet Explorer. If a script in one frame needs to create a node and append it to a document in another frame, it must use the document object for the destination frame when creating the node:

var newP = parent.frames['leftfr'].document.createElement('p');
parent.frames['leftfr'].document.body.appendChild(newP);

Using document fragments

It is also possible to deal with multiple nodes at the same time. Say for example that you want to create 10 paragraphs, and add them all to the document at the same time as each other, instead of one at a time. This can be done using a document fragment. The benefit of using this is that it creates fewer document reflows, and as a result it can improve performance for big changes.

A document fragment is like a normal element (such as a div), except that it cannot become a part of the document itself. If you try to append a document fragment to any part of a document, instead of appending the fragment, the browser will add the child nodes of the fragment. For example, you create 10 paragraphs, append them to a document fragment, then append the document fragment to the body of a document. Instead of appending the fragment to the body, it will add the 10 paragraphs as children of the body.

var frag = document.createDocumentFragment();
for( var i = 0, p; i < 10; i++ ) {
  p = document.createElement('p');
  p.appendChild(document.createTextNode('Paragraph '+(i+1)));
  frag.appendChild(p);
}
document.body.appendChild(frag);

There is still lot lot more to discuss but can’t do this on single post. I will post some more articles related to this topic to cover those things. I love javascript its really fun to play with dom …

Happy Development ..

free counters

Author Profile

Aasim Naseem
Hey, Thanks for your interest. I’m a PMP, AWS Solutions Architect, and Scrum Master certified professional with 17+ years of hands-on experience leading projects, building teams, and helping organizations deliver software solutions better, faster, and smarter.

Outside of work, I’ve got a deep curiosity for history — especially ancient civilizations like Egypt. I also enjoy reflecting on the everyday moments that shape how we live and work. This blog is my space to share insights, lessons, and thoughts from both my professional journey and personal interests.

Thanks for reading — and I hope you will find something here that matches your interest.
Latest entries
  • Economic impact of Eid ul Adha - AasimNaseem.comIslamJune 6, 2025 | Read Count: 292Economic impact of Eid-ul-Adha
  • Best PMP Exam Study Resources - AasimNaseem.comPMP CertificationMay 23, 2025 | Read Count: 497Best PMP Study Resources for 2025 (Books, Courses, Tools & More)
  • agile vs scrum - AasimNaseem.comAgile & FrameworksMay 7, 2025 | Read Count: 472Agile vs Scrum: Finally Understanding the Difference
  • When Agile shouldn’t Use - AasimNaseem.comAgile & FrameworksApril 25, 2025 | Read Count: 503When Not To Use Agile: 5 Signs You Need a Different Approach
JavaScript Changing the attribute in DOMCreating new nodes and removing existing onesDocument Object ModelDOMDOM TreeJavaScript TutorialReferencing the attribute node in DOMReferencing the text nodes in DOMUsing document fragments

Post navigation

Previous post
Next post

Related Posts

JavaScript JavaScript-AasimNaseem.com

Funny JavaScripts ::

September 21, 2009 | Read Count: 16,503April 30, 2025

Category: My Tutorials > JavaScript Hey folks … try these codes in address bar of your browser windows and see what happen … javascript:function Shw(n) {if (self.moveBy) {for (i = 35; i > 0; i–) {for (j = n; j > 0; j–) {self.moveBy(1,i);self.moveBy(i,0);self.moveBy(0,-i);self.moveBy(-i,0); } } }} Shw(6) </td javascript:R=0;…

Read More
JavaScript JavaScript-AasimNaseem.com

Event Object :: JavaScript Tutorial

July 23, 2010 | Read Count: 15,410April 30, 2025

Category: My Tutorials > JavaScriptHello All … Hope enjoying most enjoyable activity .i.e development 🙂 i love it … really love it .. Today i will try to explain something related to javascript event object. By using JavaScript, we have the ability to create dynamic web pages. Events are actions…

Read More
JavaScript JavaScript-AasimNaseem.com

How to trim string value :: JavaScript Tutorial

July 29, 2010 | Read Count: 15,472April 30, 2025

Category: My Tutorials > JavaScript Hi all.. Hope everything is good at your end. Today, there is a small tip for JavaScript users… Umm, in fact, not a tip but a utility function to trim string values… I was working on a project I had a need to trim user…

Read More

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Economic impact of Eid-ul-Adha
    Economic impact of Eid-ul-Adha
    June 6, 2025 | Read Count: 292
  • Best PMP Study Resources for 2025 (Books, Courses, Tools & More)
    Best PMP Study Resources for 2025 (Books, Courses, Tools & More)
    May 23, 2025 | Read Count: 497
  • Agile vs Scrum: Finally Understanding the Difference
    Agile vs Scrum: Finally Understanding the Difference
    May 7, 2025 | Read Count: 472
  • When Not To Use Agile: 5 Signs You Need a Different Approach
    When Not To Use Agile: 5 Signs You Need a Different Approach
    April 25, 2025 | Read Count: 503
  • Quran on Peace and Kindness
    Quran on Peace and Kindness
    April 20, 2025 | Read Count: 457

Posts from Past

  • June 2025
  • May 2025
  • April 2025
  • January 2025
  • November 2024
  • April 2024
  • October 2022
  • August 2021
  • September 2020
  • May 2020
  • April 2019
  • January 2019
  • September 2018
  • July 2015
  • June 2015
  • November 2014
  • September 2014
  • April 2014
  • June 2013
  • May 2013
  • February 2013
  • January 2013
  • December 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009

Categories List

  • Agile & Frameworks
  • Amazon Kindle
  • Android
  • Aspect Oriented Programming
  • BlackBerry
  • Blog
  • Code Repositories
  • History
  • iOS
  • Islam
  • Java
  • JavaScript
  • Life Around Us
  • Linux
  • My Bookshelf
  • My Poetry
  • My Sketch Work
  • PMP Certification
  • Random Tips
  • Saunterer Soul

Recent Posts

  • Economic impact of Eid-ul-Adha
  • Best PMP Study Resources for 2025 (Books, Courses, Tools & More)
  • Agile vs Scrum: Finally Understanding the Difference
  • When Not To Use Agile: 5 Signs You Need a Different Approach
  • Quran on Peace and Kindness

Recent Comments

  1. Aasim Naseem on When Not To Use Agile: 5 Signs You Need a Different Approach
  2. Aasim Naseem on When Not To Use Agile: 5 Signs You Need a Different Approach
  3. Masjid Wazir Khan, Lahore Pakistan - Aasim's Web Corner on Everlasting Art of Badshahi Masjid Lahore Pakistan
  4. Rishi Kumar on When Not To Use Agile: 5 Signs You Need a Different Approach
  5. Best PMP Study Resources for 2025 (Books, Courses, Tools & More) - Aasim's Web Corner on PMP Exam Eligibility 2025: 3 Things You Need to Know
©2025 Aasim's Web Corner | WordPress Theme by SuperbThemes