Scripting in the Browser - Part 2 | Page 1 | WebReference

Scripting in the Browser - Part 2 | Page 1


[next]

Scripting in the Browser - Part 2

By Sas Jacobs

Excerpted from Beginning XML with DOM and Ajax: From Novice to Professional, published by Apress, Inc. © 2006

Examining Extra Functionality in MSXML

Microsoft XML Parser (MSXML) 3, which ships with IE 6, provides some additional properties and methods that you can use with the DOM interfaces discussed previously. You'll see examples of some of these additions later, as well as how to create similar functionality in Mozilla.

Let's start by looking at extensions to the Document and Node interfaces:

Additions to the MSXML Document Interface

MSXML includes the following additions to the Document interface:

  • load()
  • loadXML()
  • readystate
  • onreadystatechange()

load(url)

The load() method loads XML content from the URL argument:

The loading happens asynchronously, which means that the method returns immediately and the parser loads the XML. As the content loads, it changes the value of the readystate property and raises the onreadystatechange event.

The load() method is also part of the DOM Level 3 Save and Load module. Mozilla supports both this method and the async property from DOM Level 3.

loadXML(xml)

The loadXML() method loads XML string data into a Document object. When called, it loads asynchronously. The method is useful for using string manipulation to create XML in JavaScript. The following line loads some simple XML content into a DOM Document from a string:

readyState

The readyState property is read-only and indicates the state of a loaded document. Table 8-2 summarizes the values for this property and their meaning.

onreadystatechange

This event fires every time the readyState property changes. You can use it to assign a handler for the event:

MSXML Node Interface Additions

MSXML includes the following additions to the Node interface:

xml nextNode() selectNodes() selectSingleNode() transformNode() transformNodeToObject()

xml

The xml property is a read-only property that returns the serialized contents of a node. In other words, it converts the raw XML into a text format:

nextNode()

This method returns the next node in the node collection:

The method will return the first node if no previous node has been selected. You can use the reset() method to return to the starting point.

selectNodes(patternString)

The selectNodes() method creates a NodeList of all nodes that match the specified XPath expression:

If no match is made, the method returns null.

selectSingleNode(patternString)

This method works in the same way as the selectNodes() method, except that it selects the first matching node:

transformNode(styleSheet)

The transformNode() method performs XSLT transformations on the current node and returns the result of the transformation as a string. This method takes a stylesheet argument, which is a DOM Document containing the XSLT stylesheet:

transformNodeToObject(styleSheet,OutputDOM)

The transformNodeToObject() method is very similar to the previous method. The difference is that it fills the OutputDOM document with the result of the transformation:

XMLHttpRequest ActiveX Object

MSXML also includes an ActiveX object called the XMLHttpRequest object. This object provides a mechanism for content to be loaded from the server and is at the heart of an approach called Asynchronous JavaScript and XML (Ajax). Mozilla and Opera offer native support for this object, and you'll find out more about both the object and Ajax in Chapter 9.

Browser Support for the W3C DOM

Now that you've seen the interfaces available in the W3C DOM, let's examine how you can use JavaScript to work with XML data stored in a DOM Document on the client. You can create a DOM Document using an ActiveX object in IE.

You can use the following code to create an instance of the MSXML parser:

Bear in mind that different versions of IE use different ActiveX objects. Mozilla creates a document using this line:

These lines are just the start of the differences between the two major browsers.

Given that the DOM implementations in MSXML and Mozilla aren't completely compatible, you need to be careful to develop client-side code suitable for both browsers. You could write code that branches to accommodate each different approach. However, a better solution is to use a wrapper to allow both browsers to exhibit the same JavaScript behaviors. This book includes the xDOM wrapper, written specifically for this chapter.

Using the xDOM Wrapper

xDOM is a JavaScript library that makes it easier to write cross-browser JavaScript code for client-side manipulation of the DOM. You can find the library in the files xDOM.js and browserDetect.js with your resources.

The wrapper needs to use a common method to create documents. It also needs to be able to provide a mechanism for Mozilla to deal with MSXML-specific methods and properties and the application of XSLT stylesheets on the client side.

Table 8-3 summarizes the functions available in xDOM.js.



Note: The xDOM library uses the "Ultimate JavaScript Client Sniffer Version 3.03" created by Netscape Communications. This is included in the code directory (as browserDetect.js), along with xDOM.js. You need to include both of these JavaScript files to use xDOM.

xDOM Walkthrough

This section walks through the xDOM.js file and describes the code therein. If you aren't interested in the details of the xDOM wrapper, please feel free to skip ahead to the "Using JavaScript with the DOM" section.

The code starts by declaring global variables that library functions will use. The most important line follows:

This line creates an array of strings that contain the ProgIDs for creating different versions of the MSXML DOMDocument object.

The next step initializes the wrapper. The method used depends on the browser version.

Initializing in IE

For IE, the initialization code determines which version of MSXML a user has available on his or her machine by iterating through the arrMSXMLProgIDs array:

Initializing in Mozilla

The Mozilla initialization code is slightly more complicated. It makes use of JavaScript prototypes, which allow you to add methods or properties to objects at run-time. In this case, the code adds methods that mimic the way that MSXML behaves:

Note that _Moz_Document_load is a function that the wrapper declares later.

The preceding code replaces the default load method in the Mozilla DOM with a new method, _Moz_Document_load(). It keeps a reference to the default method by first assigning it to a prototype of a different name, Document.prototype.__load__. The wrapper must do this because it still needs to call the original method from within the new method. From an objectoriented perspective, this is like overriding a method and then calling that method on the super/parent class within the new method implementation.The wrapper also declares a new event handler called onreadystatechange:

The wrapper initially assigns the event handler a null value. Later, the wrapper attaches code that runs when the event fires.

The final prototype declares a Getter method to get the value of a variable:

A Getter method appears as a property to the end user, but is implemented as a function. You don't need a corresponding Setter method because the xml property is read-only.

xDOM.createDocument() Method

The xDOM.createDOMDocument() is the only method that you call with JavaScript—in other words, it's a public method. This method determines which browser is being used and creates a DOM Document object using the appropriate method for that browser.

The method also attaches an event handler to the Mozilla load event so that you can raise this event in the same way as in IE:

Private xDOM Library Functions

The remainder of the library file contains the implementations of the prototypes that you declared earlier. You can look through these to see how Mozilla natively handles some of its more advanced XML features.

The first method implemented is the Mozilla version of the MSXML loadXML() method. This uses the XMLParser object that is included in the Mozilla XMLExtras library. This library ships with all Mozilla installations:

This method copies the nodes from the newly parsed DOM.

The Moz_Document_load() overrides the Mozilla load() method. This allows the wrapper to include code for firing the MSXML equivalent events:

The updateReadyState() function is a helper method that sets the readyState property and fires the necessary events:

The two functions that deal with XSLT are very similar. The only difference is that one of them serializes the result to a string, and the other returns the processed result as a DOM Document object. Both functions allow the Mozilla XSLTProcessor object to mimic XSLT transformations in MSXML:

Some of the extra functions in the wrapper aren't included in this brief walkthrough. You can look through the code if you want to explore further.

WHY EXTEND MOZILLA?
Given that the Mozilla implementation is more standards-compliant, you may be wondering why you're using a JavaScript wrapper that makes Mozilla work like IE. MSXML is a separate library from IE, so it's not possible to extend it with JavaScript prototypes. IE was the first browser to support XML and is still the most popular web browser. By replicating the behavior of IE, you can use the large number of IE-specific examples available on the Internet in your own projects more easily.

xDOM Caveats

There are some important points to note when using xDOM. The first is that the wrapper cannot check the version of XSLT supported by the DOM Document you create. If you need to support much older browsers, you may need to load a different XSLT document based on the version of MSXML installed. You can do this by looking at the value of the strMSXMLProgID variable initialized when the xDOM library loads.

The xDOM library doesn't allow the free threaded version of the MSXML DOM Document to be created. The free threaded version is most important when running code on the server side. The object uses a different threading model to interact with the operating system, and this is important when there are multiple requests for the DOM Document at the same time, as in serverside applications.

The xDOM wrapper doesn't provide a complete solution to the differences between MSXML and Mozilla. You still need to test your application rigorously in all browser versions that you're targeting. I checked xDOM with IE 6.0 and Mozilla 1.0.

So far, you've seen some of the theory behind scripting the DOM. Now it's time to look at how to apply this code in some examples.


[next]

URL: