spacer

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

home / programming / javascript / domwrapper To page 1To page 2To page 3To page 4current page
[previous]

A Cross-Browser DOM Document Wrapper

Senior Systems Engineer – Disk-Based Backup/Replication (PA)
Next Step Systems
US-PA-Philadelphia

Justtechjobs.com Post A Job | Post A Resume
Developer News
News Flash: Adobe Has iPhone Workaround
Adobe's Flash 10.1 Goes Mobile (Minus iPhone)
A Salute to Visionary CEOs


Error Handling

We've now come to the last part of our project, error handling. As I'm sure you can guess, IE and Mozilla do it two different ways. IE's DOM Document has a parseError attribute that is filled with an error code if an error occurs. However, an error in the DOM Document does not throw a JavaScript error, so execution does not stop. In Mozilla, any error inside the load() method is thrown as a JavaScript error, and execution stops cold. So once again, we will make Mozilla more like IE and create a parseError attribute.

The parseError attribute starts out as 0, which indicates that there is no error. Whenever someone wants to check if there has been an error, a simple check to see if the parseError attribute is not equal to 0 does the trick. So let's start out by adding our parseError attribute with a default value of 0:

Document.prototype.parseError = 0;

Next, we will add a try...catch block in our _Document_load() method. Because it would be impossible to map all of the errors in Mozilla to their IE counterparts, we'll just set the parseError attribute to –9999999 to indicate that there is an error (we will also change the readyState attribute to indicate the loading action is done). Important thing to note: we must set the parseError attribute to 0 every time the load() method is called, because it is essentially wiping the slate clean for the Document object:

function _Document_load(strURL) {
 
    //set the parseError to 0
    this.parseError = 0;
 
    //change the readyState
    changeReadyState(this, 1)
    
    //watch for errors
    try (
        //call the original load method
        this.__load__(strURL);
        
    } catch (objException) {
    
        //set the parseError attribute
        this.parseError = -9999999;
        
        //set readyState to 4, we are done loading
        changeReadyState(this, 4);
 
    } // End: try...catch
}

And here's another interesting wrinkle: if an error is caused while parsing, Mozilla doesn't throw an exception. Instead, it creates an XML string containing the details of the error, for example:

<parsererror xmlns="http://www.w3.org/1999/xhtml">XML Parsing Error: mismatched tag. Expected: </root>. Location: file:///C:/DOCUME~1/Nicholas/MYDOCU~1/MYARTI~1/USINGT~1/Example/Invalid.xml Line Number 3, Column 37:<sourcetext> <root image="root.gif">My Root</boot> ------------------------------------^</sourcetext></parsererror>

So, we actually need to check for an error after the XML is loaded to see if one of these XML error strings has been generated (or if there is no documentElement for some reason). Because we have incredible foresight, we will create a function called handleOnLoad() to encapsulate this process. The handleOnLoad() function will take one parameter, the Document to check. It will also set the readyState attribute to 4 (regardless of any errors, the loading is over):

function handleOnLoad(objDOMDocument) {
    //check for a parsing error
    if (!objDOMDocument.documentElement || objDOMDocument.documentElement.tagName == "parsererror")
        objDOMDocument.parseError = -9999999;
 
    //change the readyState
    changeReadyState(objDOMDocument, 4);
}

Now, we need to add this into two places, the _Document_onload() function and the loadXML() method (note that we aren't adding it to the _Document_load() function, because we can only determine parsing errors after the XML has been loaded):

function _Document_onload() {
 
    //handle the onload event
    handleOnLoad(this);
}
 
    //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
        
        //we can't fire the onload event, so we fake it
        handleOnLoad(this);
        
    } //End: function

Now the parseError attribute should be fairly accurate for Mozilla.

Conclusion

After a somewhat lengthy trek, we have created our cross-browser (IE5/NS6) DOM Document wrapper. To review, you can now create a DOM Document object by doing the following:

var objDOMDocument = jsXML.createDOMDocument(strNamespaceURI, strRootTagName);

You can load an XML string into the DOM Document by doing:

objDOMDocument.loadXML("<myroot />");

You can retrieve the XML string by doing:

var strXML = objDOMDocument.xml;

To load an external XML file, we do the following:

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

To load it asynchronously:

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

You can set an event handler to determine when an XML file has been fully loaded by doing:

objDOMDocument.onreadystatechange = myFunction;
 
function myFunction() {
  if (this.readyState == 4)
    alert("Loaded");
}

And to check for errors, you can do the following:

if (objDOMDocument.parseError != 0)
  alert("Error");

We are now ready to use a DOM Document the same way across Internet Explorer 5.0+ (Windows) and Mozilla (Mozilla or Netscape 6.1+). This example illustrates all of these uses. I ask that you try it in both browsers. There are slight differences, but the overall functionality is the same.

About the Author

Nicholas C. Zakas is a user interface designer for web applications at MatrixOne, Inc. in Massachusetts. Nicholas works primarily as a client-side developer using JavaScript, DHTML, XML and XSLT. He can be reached via e-mail at nicholas@nczonline.net or at his Web site, http://www.nczonline.net.


home / programming / javascript / domwrapper To page 1To page 2To page 3To page 4current page
[previous]

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

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

webref The latest from WebReference.com Browse >
Building a Banking Application Home Page with OOP · Mixing Scripting Languages · Review: phpFox, a Social Networking CMS with all the Bells and Whistles
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Enterprise 2.0: Social Networking in the Cloud · BroadSoft Marketplace Hastens Pace of Telephony Innovation · Review: HTC Hero for Sprint

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

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