spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / javascript / domwrapper To page 1To page 2To page 3current pageTo page 5
[previous] [next]

A Cross-Browser DOM Document Wrapper

Developer News
Mandrake Linux Founder Back, Virtually
Amazon: We're a Technology Company
Sun Expands MySQL With Closed Source

The readyState Attribute and onreadystatechange Event

As mentioned earlier, there is a load() method on the DOM Document in both IE and Mozilla that allows the developer to load an XML file directly into the DOM Document. Naturally, there also must be a way to determine when the XML file has been fully loaded. As usual, IE and Mozilla take different approaches to this.

In IE, the DOM Document has a readyState attribute. The readyState attribute is an integer value indicating what the current state of loading is. These values are:

CodeStringDescription
0uninitializedThe DOM Document has been created, but the load() method has not yet been called.
1loadingThe load() method has been called and is executing.
2loadedLoading is complete, the DOM Document is now parsing the file.
3interactiveSome of the XML data has been parsed, the DOM Document is now available, but is incomplete and read-only.
4completedThe XML data has been fully parsed and the DOM Document is available in its entirety.

In addition, IE also provides a readystatechange event that can have an event handler assigned to it. Every time the readyState attribute changes, the readystatechange event fires. So, if you assign a function to the onreadystatechange event handler, you can easily see if the DOM Document is done loading.

Switching back to Mozilla for a moment, their approach is totally different, if not a bit more logical. Mozilla fires a load event when the DOM Document is done loading. So, by assigning the onload event handler, you can be alerted when the DOM Document is completely loaded. This differs from IE's method in that there are not various states of loading: the DOM Document is either loaded or it is not, and there is no attribute to tell you this. Once again, it is our job to tame Mozilla to behave more like IE.

First, we will add the readyState attribute to the Document class and initialize it to 0:

Document.prototype.readyState = "0";

Now comes the interesting challenge. There are five possible values of readyState. We know that we can simulate the first, 0, because nothing has happened. Which of the others can we simulate? Looking it over quickly, two of the remaining four are doable.

If we can listen in on the load() method, we can set the readyState value to 1 just before it executes. Also, when the Mozilla load event is fired, we can change the readyState to 4. For 2 and 3 there's just no way of knowing this information at the present time.

Let's begin with the task of "listening in" on the load() method. Of course, there is no way to actually do that. What we need to do is save the original load() method into another variable, then define our own load() method that changes the readyState attribute and then calls the original method. Sound confusing? Let's break it down:

First, save a reference to the current load() method into a "hidden" __load__ attribute:

Document.prototype.__load__ = Document.prototype.load;

Next, set the load() method to point to our own function:

Document.prototype.load = _Document_load;

Now, when someone calls load() on the Document, it will call our _Document_load() function. So let's define that function:

function _Document_load(strURL) {
 
    //change the readyState
    this.readyState = 1;
    
    //call the original load method
    this.__load__(strURL);
}

Now, when the load() method is called, the readyState will accurately change to 1. So how about when the XML has been fully loaded? This is a little bit different.

In order to change the readyState attribute to 4, we need to add an event listener to the Document's load event. This can't be done until the Document is instantiated, which means that this must be done back in the createDOMDocument() function:

    //determine if this is a standards-compliant browser like Mozilla
    if (isMoz) {
    
        //create the DOM Document the standards way
        objDOM = document.implementation.createDocument(strNamespaceURI, strRootTagName, null);    
    
        //add the event listener for the load event
        objDOM.addEventListener("load", _Document_onload, false);
        
    }

By adding this line, when the XML data has finished being loaded, it will call our _Document_onload() function, which is as follows:

function _Document_onload() {
 
    //change the readyState
    this.readyState = 4;
 
}

We can't forget about our loadXML() method. The readyState attribute also changes when it is called, so let's update our code:

    //add the loadXML() method to the Document class
    Document.prototype.loadXML = function(strXML) {
    
        //change the readystate
        this.readyState = 1;
 
        //create a DOMParser
        var objDOMParser = new DOMParser();
        
        //create new document from string
        var objDoc = objDOMParser.parseFromString(strXML, "text/xml");
        
        //make sure to remove all nodes from the document
        while (this.hasChildNodes())
            this.removeChild(this.lastChild);
            
        //add the nodes from the new document
        for (var i=0; i < objDoc.childNodes.length; i++) {
            
            //import the node
            var objImportedNode = this.importNode(objDoc.childNodes[i], true);
            
            //append the child to the current document
            this.appendChild(objImportedNode);
        
        } //End: for
        
        //change the readystate
        this.readyState = 4;
        
    } //End: function

Congratulations, we've now completed our exercise in mimicking the IE readyState attribute. Our next task: mimic the readystatechange event.

This step is actually not all that difficult. Let's assume someone wants to assign an event handler for the readystatechange event. They would do it without using IE's attachEvent() method or Mozilla's addEventListener() method. In short, they would use the old-fashioned way of assigning an event handler, as:

objDoc.onreadystatechange = myFunction;

If this is the case, then we can make an onreadystatechange attribute in Mozilla's Document class, and then just call it each time we change the readyState attribute. So, let's start by adding the attribute:

Document.prototype.onreadystatechange = null;

Next, we need to go back to the places we changed the readyState attribute and call the onreadystatechange function (if there is one). Since this may be done in several areas, we'll make a changeReadyState() function to encapsulate the functionality. The changeReadyState() function will take two parameters: the Document object to change and the value to set the readyState attribute to. Here's the code for this function:

function changeReadyState(objDOMDocument, iReadyState) {
 
    //change the readyState
    objDOMDocument.readyState = iReadyState;
    
    //if there is an onreadystatechange event handler, run it
    if (objDOMDocument.onreadystatechange != null && typeof objDOMDocument.onreadystatechange == "function")
        objDOMDocument.onreadystatechange();
}

Now, let's go and put this into the load() method and load event handler:

function _Document_load(strURL) {
 
    //change the readyState
    changeReadyState(this, 1);
    
    //call the original load method
    this.__load__(strURL);
 
}
 
function _Document_onload() {
 
    //change the readyState
    changeReadyState(this, 4);
}

We also need to update the loadXML() method that we wrote for the Document class:

    //add the loadXML() method to the Document class
    Document.prototype.loadXML = function(strXML) {
    
        //change the readystate
        changeReadyState(this, 1);
 
        //create a DOMParser
        var objDOMParser = new DOMParser();
        
        //create new document from string
        var objDoc = objDOMParser.parseFromString(strXML, "text/xml");
        
        //make sure to remove all nodes from the document
        while (this.hasChildNodes())
            this.removeChild(this.lastChild);
            
        //add the nodes from the new document
        for (var i=0; i < objDoc.childNodes.length; i++) {
            
            //import the node
            var objImportedNode = this.importNode(objDoc.childNodes[i], true);
            
            //append the child to the current document
            this.appendChild(objImportedNode);
        
        } //End: for
        
        //change the readystate
        changeReadyState(this, 4);
        
    } //End: function

With this in place, a developer has a common way to determine if a file has been loaded. When the file is finished loading, the onreadystatechange event handler is called. Within that function, you can check the value of readyState. If it is 4, then you know the file has been loaded and you are ready to roll.

A Quick Note on Loading External Files

The DOM standards support both synchronous and asynchronous loading of external XML files. Both the IE ActiveX version and the Mozilla native version support the async property on a DOM Document, such as the following:

objDOMDocument.async = true;

If async is set to false, the external XML file begins to load, but control is returned to the next line of JavaScript before the file has finished loading. If async is set to true, then control is not returned to the next line of JavaScript until the file has finished loading.

This is usually set just before loading a file, such as:

objDOMDocument.async = true;
objDOMDocument.load("myfile.xml");

home / programming / javascript / domwrapper To page 1To page 2To page 3current pageTo page 5
[previous] [next]

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Whitepapers and eBooks

Symantec Whitepaper: Converging System and Data Protection for Complete Disaster Recovery
Intel Whitepaper: Comparing Two- and Four-Socket Platforms for Server Virtualization
IBM Solutions Brief: Go Green With IBM System xTM And Intel
HP eBook: Simplifying SQL Server Management
IBM Contest: Are You the Next Superstar? Join the "Search for the XML Superstar" Contest to Find Out
Microsoft PDF: Top 10 Reasons to Move to Server Virtualization with Hyper-V
Microsoft PDF: Six Reasons Why Microsoft's Hyper-V Will Overtake Vmware
Microsoft Step-by-Step Guide: Hyper-V and Failover Clustering
Intel PDF: Quad-Core Impacts More Than the Data Center
Intel PDF: Virtualization Delivers Data Center Efficiency
Go Parallel Article: PDC 2008 in Review
Microsoft PDF: Top 11 Reasons to Upgrade to Windows Server 2008
Avaya Article: Communication-Enabled Mashups: Empowering Both Business Owners and IT
Intel Whitepaper: Building a Real-World Model to Assess Virtualization Platforms
  PDF: Intel Centrino Duo Processor Technology with Intel Core2 Duo Processor
Microsoft Article: Build and Run Virtual Machines with Hyper-V Server 2008
Go Parallel Article: Q&A with a TBB Junkie
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
IBM eBook: The Pros and Cons of Outsourcing
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Symantec Whitepaper: Comprehensive Backup and Recovery of VMware Virtual Infrastructure
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
webref The latest from WebReference.com Browse >
Popular JavaScript Framework Libraries: An Overview - Part 3 · Accessing Your MySQL Database from the Web with PHP · Working with the DOM Stylesheets Collection
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Fixing MySQL Replication · Firewall Guide: First Steps to Securing the Enterprise · VoxOx Tames the Tumultuous Communications Tangle

Created: June 13, 2002
Revised: June 13, 2002

URL: http://webreference.com/programming/javascript/domwrapper/4.html