Team LiB
Previous Section Next Section

Chapter 21: Browser-Specific Extensions and Considerations

The majority of this book focuses on features you can use across a wide range of browsers, features that are somewhat standardized, either officially or unofficially through widespread adoption. In this chapter we instead take a look at features and characteristics specific to particular browsers. An awareness of these features can be useful if you’re working in an environment where browser uniformity is guaranteed, or if you wish to provide enhancements for a subset of your users.

Internet Explorer

While browser demographic statistics vary wildly from survey to survey, one statistic is clear: Microsoft Internet Explorer is hands-down the most widely deployed browser today. Microsoft has implemented a variety of proprietary features, most of which are seldom used. In this section we cover some historical background that might be useful, and introduce some of the more advanced proprietary features that IE offers.

JScript

Microsoft refers to its implementation of ECMAScript as “JScript” to avoid trademark and licensing issues (“JavaScript” is a trademark of Sun Microsystems). Like Netscape’s “JavaScript,” different versions of JScript are implemented in the various versions of the browser. Table 21-1 shows the correspondence between Microsoft’s JScript language implementation and IE browser versions.

Table 21-1: Relationship Between JScript Language and Browser Version

Language Version

Browser Version

JScript 1.0

Internet Explorer 3.0

JScript 3.0

Internet Explorer 4.0

JScript 5.0

Internet Explorer 5.0

JScript 5.5

Internet Explorer 5.5

JScript 5.6

Internet Explorer 6.0

Different versions of JScript correspond to different degrees with the ECMAScript standard. Table 21-2 lists the relationship between JScript versions and the standard.

Table 21-2: Relationship Between Microsoft JScript and ECMA Script

Microsoft Version

Standard Version

Exceptions

JScript 1.0

Very loose conformance to ECMA-262 Edition 1

Many, and some extra features (even though ECMAScript is based in part on JScript 1.0)

JScript 3.0

Strict conformance to ECMA-262 Edition 1

Includes some extra features

JScript 5.0

Strict conformance to ECMA-262 Edition 1

Includes many extra features

JScript 5.5

Strict conformance to ECMA-262 Edition 3

Includes some extra features

JScript 5.6

Strict conformance to ECMA-262 Edition 3

Includes some extra features

The first JScript implementation (JScript 1.0) available in Internet Explorer 3 was essentially a Microsoft clone of Netscape’s JavaScript 1.0 found in Netscape 2. However, Internet Explorer 3 was released at roughly the same time as Netscape 3, which included JavaScript 1.1. This led to a “feature lag”—Microsoft browsers implemented core language features one “generation” behind those of Netscape. Over time this lag grew smaller and smaller, to the point that the latest releases of the browsers implement essentially the same features set. This is apparent from the fact that Internet Explorer 5.5 and Netscape 6+ are compliant with Edition 3 of the ECMAScript standard. Examining these parallels allows one to draw the rough correspondence between core JavaScript in Netscape and Microsoft browsers found in Table 21-3. Remember, this correspondence is only an approximation, so you should always look up the specific feature you are interested in before making assumptions.

Table 21-3: Rough Correspondence Between Microsoft and Netscape/Mozilla JavaScript

Language Version

Browser Version

Language Version

Browser Version

JavaScript 1.0

Netscape 2.0

JScript 1.0

Internet Explorer 3.0

JavaScript 1.3

Netscape 4.06

JScript 3.0

Internet Explorer 4.0

JavaScript 1.5

Netscape 6+, Mozilla-based browsers

JScript 5.5

Internet Explorer 5.5+

Noteá

Some would argue that JavaScript 1.1 or 1.2 is a better match for JScript 3.0. While this contention is certainly plausible, the adherence to the ECMAScript standard in JavaScript 1.3 and JScript 3.0 was the chief factor in drawing the correspondence in Table 21-3. Thankfully, there is not as wide a disparity in core language features among browsers as there is in object models.

In the remainder of this section we briefly discuss some of the major differences among versions of JScript. If you are having trouble with one of your scripts under older browsers, this section is a good place to check for when features made it into the language. For example, developers may wonder why their do/while loops will not work under IE3. The reason is that this feature was included only starting with JScript 3.0, so it is only found in IE4+.

Noteá

For detailed information regarding language features, the canonical place to look is Microsoft’s JScript documentation, available at http://msdn.microsoft.com/scripting/.

JScript 1.0

JScript 1.0 in Internet Explorer 3.0 was very similar to what Netscape 2.0 supported, and the browser supported almost the exact same object model. However, one huge difference between Netscape and Microsoft existed during this generation of browsers—case sensitivity. JScript 1.0 is generally not case-sensitive, so you can get away with changing the case of common methods and objects without penalty. This characteristic caused a great deal of confusion for many new JavaScript programmers who used only Internet Explorer. Other than that, the only major concern people should have with JScript 1.0 is that Internet Explorer 3.0 did not support the src attribute of the <<script>> tag until the 3.02 release of the browser. The specific nuances of this implementation have more historic interest than utility.

JScript 2.0

Although JScript 2.0 was not originally a part of a browser release, it was made available in later versions of IE3 and included in Microsoft’s Internet Information Server (IIS) 1.0. The features new to JScript 2.0 were included in JScript 3.0, so the items listed here are for the most part also new to Internet Explorer 4 (though it implements JScript 3.0).

  • The Array object. JScript 1.0 did not implement arrays as objects, so you had to use literal notation to create them. The length property and the join(), reverse(), and sort() methods were also added in this version.

  • Many improvements to functions, including the implicitly filled arguments[] and caller properties as well as the Function object.

  • Many improvements to numbers, including the Number object and its constants Number.MAX_VALUE, Number.MIN_VALUE, and Number.NaN, as well as the global constants NEGATIVE_INFINITY and POSITIVE_INFINITY.

  • The Boolean object.

  • Maturity of objects, which now includes the toString() and valueOf() methods and the prototype property (though no Object is available in this release).

  • The void operator.

JScript 3.0

The core language features of this version are ECMAScript-compliant and were included in IIS 4.0 as well as IE4. You can see from the new features listed here that this version marks a major release for the language.

  • A complete overhaul of Date to render it ECMAScript-compliant.

  • Regular expressions, including the RegExp object.

  • New Array methods: concat() and slice().

  • Many new methods for String: concat(), fromCharCode(), slice(), split(), and substr().

  • ECMAScript-compliant type conversion.

  • The ability to delete object properties and array elements.

  • New flow control mechanisms, including the do/while loop, the ability to label statements, and switch.

  • Further improvements to numbers, including the global Infinity and NaN constants and isFinite() method.

  • The Object object.

  • Full support for Unicode.

Microsoft made several proprietary extensions to the language core as well. A brief overview of these features appears in Table 21-4.

Table 21-4: Proprietary Extensions to JScript in Version 3.0

Feature

Description

ActiveXObject object

Allows scripts to create instances of ActiveX components in order to harness extended functionality; for example, an Excel spreadsheet. This feature is discussed in more detail later in the chapter.

Enumerator object

Enables iteration of Microsoft collections similar to for/in loops on objects. This object is discussed in more detail later in the chapter.

VBArray object

Permits JavaScript to use “safe” VBScript arrays.

Conditional compilation

Allows dynamic definition and execution of code (rather than linear runtime “compilation”). This feature is described in more detail later in the chapter.

JScript 4.0

This language version was never included as part of a browser release. Rather, it was included in Microsoft Visual Studio. However, JScript 4.0 is for all intents and purposes the same as JScript 3.0, just repackaged and renamed for inclusion with another application.

JScript 5.0

Version 5.0 of JScript marks the beginning of support for advanced exception handling. Included is the try/catch construct discussed in Chapter 23, the Error object, and the throw statement for generating custom error conditions. The only other major additions in this version are the for/in loop for iterating over object properties and the instanceof operator.

JScript 5.5

JScript 5.5 corresponds closely to JavaScript 1.5 and is in compliance with ECMAScript Edition 3. The new features are listed here:

  • Improvements to functions, including the implicitly filled callee property, as well as the call() and apply() methods. A length property was included with a function’s arguments to indicate the actual number of parameters passed.

  • The new String method charCodeAt().

  • Global decodeURI() and encodeURI() methods, offering similar functionality to the existing escape() and unescape().

  • Stack and Queue methods for Array: pop(), push(), shift(), and unshift(). In addition, the splice() method was also added.

  • Various useful enhancements to regular expressions.

  • Numerous global conversion functions, such as toExponential(), toFixed(), toPrecision(), toTimeString(), and toDateString().

Proprietary JScript Features

Although the core language capabilities of JScript have not strayed too far from mainstream JavaScript, Microsoft does implement a few unique features. Some features like collections have been a widely used part of the language for quite some time and have even been adopted into Web standards.

Targeting Internet Explorer

Since the features discussed in this section are specific to Internet Explorer, it makes sense to hide them from other browsers. The easiest way to do this is with the language and type attributes of the <<script>> tag. IE recognizes “JScript” as a valid language value, and “text/jscript” as a valid type value. Other browsers do not, and will therefore ignore the contents of such a script. So, when writing IE-specific scripts, you might use

<<script language="JScript">>
// IE-specific JavaScript
<</script>>

Or if you were still concerned about validation, you would dump the language attribute and focus only on type:

<<script type="text/jscript">>
// IE-specific JavaScript
<</script>>

Collections

A potentially confusing aspect of the Internet Explorer Document Object Model is its liberal use of collections. A collection is a container object holding heterogeneous data that may be accessed by ordinal (that is, by index) or by name. They are often mistaken for arrays because the functionality of the two data types is so similar. For example, the document object “arrays,” such as document.all and document.images, are actually collections. In addition, the “arrays” of HTML elements found in the W3C DOM are collections as well (HTMLCollection objects, to be specific). Although the discussion immediately following applies to Netscape 6+ and other DOM-compliant browsers, collections are most often used in the context of Internet Explorer document objects, so we focus our discussion here on using collections in Internet Explorer.

Collections are used to hold groups of (X)HTML element objects. For example, document.all holds an object for each markup element (and comment) in the page. There are many ways to access the members of a collection, but they are most often retrieved by name. To retrieve a particular object, you use the value of the element’s id or name attribute. All the following syntaxes are valid:

collectionName.name
collectionName["name"]
collectionName("name")
collectionName.item("name")
// namedItem() only supported in Internet Explorer 6+
collectionName.namedItem("name")        

When indexing a collection with a non-numeric string, the interpreter first searches for any member of the collection with id matching the given name, then for any member with a matching name. If multiple elements match the given name, they are returned as a collection.

Accessing a member by ordinal has similar syntax. Because collection indices are zero-based, you could access the third element of a collection with any of the following:

collectionName[2]
collectionName(2)
collectionName.item(2)

Note that the collectionName() syntax is just shorthand for collectionName.item(). We mentioned previously that when accessed by name, a collection returns a collection of members if there are multiple matching elements. In this case, you can combine the two forms of access to select one of the members of the collection returned. For example, if you are interested in the second of multiple items named “myElement,” you might write

collectionName.item("myElement").item(1);

Internet Explorer provides convenient shorthand for this operation. You can pass the index of the item you are interested in as the second parameter to the item() method. The following is equivalent to the previous example:

collectionName.item("myElement", 1);

The other standard properties of collections are length, indicating how many members the collection holds, and tags(), which accepts a string indicating an (X)HTML tag and returns a collection of all the objects created from that tag. For example, to retrieve a collection of all element objects corresponding to <<p>> tags in the document, you might write

var pTags = document.all.tags("p");

Some collections—for example, the options collection of a Select object—also have add() and remove() methods.

The Enumerator Object

Because accessing a collection results in the retrieval of a collection when multiple members share the same name or id, there is no apparent way to iterate over each member. You might think that a for/in loop would work, but unfortunately for/in loops are used with objects, not collections. Instead, Internet Explorer uses an Enumerator object reminiscent of an iterator in C++.

When a collection is passed to the Enumerator() constructor, an Enumerator instance is created that can be used to step through each item in the collection. Using an object to step through each element has several advantages, most obviously that references to it can be passed around as data in a way that would be impossible otherwise. The methods of Enumerator objects are listed in Table 21-5.

Table 21-5: Methods of Enumerator Objects

Method

Description

>atEnd()

Returns a Boolean indicating if the enumerator is at the end of the collection.

>item()

Retrieves the current item.

>moveFirst()

Moves to the first item in the collection.

>moveNext()

Moves to the next item in the collection.

The following code illustrates how to use an Enumerator. The script passes document.all to the Enumerator() constructor and then uses the resulting object to iterate over all the tags

in the page.

<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<<html xmlns="http://www.w3.org/1999/xhtml">>
<<head>>
<<title>>Enumerator Example<</title>>
<<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />>
<</head>>
<<body>>
<<h2>>Enumerator Example<</h2>>
<<p>>Here's some text.<</p>>
<<h3>>Tags<</h3>>
<<script type="text/jscript">>
<<!--
var element;
var e = new Enumerator(document.all);
while (!e.atEnd())
{
  element = e.item();
  document.write(element.tagName + "<<br />>");
  e.moveNext();
}
// -->>
<</script>>
<<!--   Body to be written out -->>
<</body>>
<</html>>

The result is shown in Figure 21-1.

Click To expand
Figure 21-1: Using an Enumerator to iterate over all the elements in the page

Conditional Compilation

JScript 3.0 and later versions include conditional compilation features similar to those of the preprocessor in C. Conditional compilation directives enable access to special environmental variables giving information about the client platform. These directives can be used in conditional expressions to include or exclude code to be (or not to be) interpreted. The idea is to use these directives to test for specific conditions—for example,

a debugging flag or a platform providing extended capabilities—and to modify the code seen by the interpreter accordingly.

The conditional compilation directives are very simple. All are prefixed with the @ symbol and have typical preprocessor syntax. The most important syntax is the if/else statements, which are straightforward:

@if (conditional)

body

[@elif (conditional)

body]

...

[@else

body]

@end

The browser provides many predefined variables for use with conditional compilation. These variables are described in Table 21-6. Any conditional compilation variable that is not defined or not true behaves as NaN.

Table 21-6: Conditional Compilation Variables

Variable

Description

>@@_win32

True if the machine is running a 32-bit Windows system.

>@@_win16

True if the machine is running a 16-bit Windows system.

>@@_mac

True if the machine is running an Apple Macintosh system.

>@@_alpha

True if the machine is a DEC/Compaq Alpha.

>@@_x86

True if the machine is an x86 processor (that is, Intel 80x86, Pentium, and clones).

>@@_mc680x0

True if the machine is a Motorola 680x0.

>@@_PowerPC

True if the machine is a PowerPC processor.

>@@_jscript

True if JScript is in use (always true).

>@@_jscript_build

Number indicating the building number of the JScript engine.

>@@_jscript_version

Number indicating the major and minor JScript version in use. Format is major.minor (e.g., 5.5).

You can set and manipulate new variables with identifiers beginning with @ during conditional compilation. The syntax for setting a variable of this kind is

@set @identifier = value

The value is an expression of other @ variables, Booleans, numbers, and normal arithmetic and bitwise operators. Strings are not allowed. You can use a variable set this way in future conditional compilation statements or even in “normal” JavaScript. For example,

<<script type="text/jscript">>
@set @debugging = true
@if (@debugging)
   alert("Debugging is on because the value of @debugging is: " + @debugging);
@end
<</script>>

gives this result:

Click To expand

While you can include conditional compilation directives directly in your scripts, doing so might confuse non-JScript browsers. For this reason it is almost always better to place these directives within comments. Internet Explorer will look within comments for conditional compilation directives if you use the @cc_on directive before any others.

You must also indicate the comments containing conditional compilation statements by beginning them with an @ directive and closing them with an @ symbol. For example:

<<script type="text/jscript">>
/*@cc_on @*/
/*@set @debugging = true@*/
<</script>>

Because the processing of conditional compilation directives happens before normal script interpretation, you can use it to selectively enable or disable pieces of code. Consider the following script that defines one of two functions depending upon which version of JScript (if any) is supported:

<<script type="text/javascript">>
/*@cc_on @*/
/*@if (@_jscript_version >>= 5)
function doTask()
{
  // some code using advanced IE5+ features
  alert('IE Specific code!');
}
@else @*/
function doTask()
{
  // some code using standard browser features
  alert('Non-IE Specific code!');
}
/*@end @*/
doTask();
<</script>>

A JScript 3+ browser processes the conditional compilation directives and defines the first doTask() if JScript 5+ is in use. Otherwise, the second definition is used. Browsers not supporting conditional compilation simply ignore everything in the comments and use the second definition as a result.

This technique can be very useful for defining functions that harness advanced platform- or version-specific features but that still degrade gracefully under other browsers.

Proprietary Browser Features

Microsoft is the undisputed king of proprietary browser features. More than any other vendor, Microsoft shows continual initiative in bundling new technologies with its browsers. While many critics argue that these new technologies increase Microsoft’s domination of the browser market by perpetuating users’ reliance upon proprietary Microsoft technologies, the utility of some of Internet Explorer’s more advanced features is undeniable. The surprising aspect of these innovations is not in their capabilities or the extent of their integration with the operating system. Indeed, Microsoft has made it clear that increased integration of the Web with Windows and related software products is one of its primary goals. Rather, the surprising aspect of these features is how few developers are aware of their existence.

In this section we give a brief overview of some of the new, proprietary features found in each version of Internet Explorer. While some of these features are not, strictly speaking, features of JavaScript itself, they are often close enough in functionality to be of interest to Web developers programming for Internet Explorer. Because of the sheer volume of proprietary features found in newer versions, we have chosen at times to highlight some of the most useful features and to omit some secondary or lesser-used capabilities. We’ll cover some of the most useful features in the sections that follow. Full documentation of Internet Explorer is always available from the Microsoft Developer Network (MSDN) at http://msdn.microsoft.com.

Internet Explorer 3

As the first browser providing JScript support, it is not surprising that Internet Explorer 3 implements only a few proprietary features not found in other browsers. Most notable are support for ActiveX controls and embedded objects signed via Authenticode technology. This browser version also supports the basic LiveConnect functionality discussed in Chapter 18.

There are a few issues to be aware of with IE3. Some early versions apparently have problems loading externally linked JavaScript libraries. Further, as previously mentioned, certain aspects of IE3’s JScript implementation are case-insensitive, so you will need to exercise caution when using very old scripts. Although the shift to newer versions of the browser makes these problems less of a concern, they do rear their heads from time to time.

Internet Explorer 4

The divergence of object models discussed in Chapter 9 contributed to a large number of the proprietary features in IE4. Because there was no programming language–independent and vendor-neutral standard for how elements were to be exposed to scripts, each vendor implemented its own object model. Aside from the obvious proprietary Document Object Model, IE4 introduced some features that begin to blur the line between an active Web document and a full-blown application. A general overview of the proprietary features introduced in IE4 is given in Table 21-7, and some of these features are covered in more detail in following sections.

Table 21-7: Some Proprietary Features Introduced in Internet Explorer 4

Feature

Description

IE DHTML

The ability to dynamically manipulate documents according to Internet Explorer's Document Object Model. Primarily document.all and access to the style object of an element is the main way IE DHTML is implemented.

window.external

Allows scripts to access extended object model features provided by the client (e.g., a Browser Helper Object). For more information, see the MSDN.

IE Event model

Internet Explorer's proprietary event model (event bubbling) as well as proprietary event handlers.

CSS Filters

Offers a variety of nonstandard special effects for fonts and page transitions.

Data Binding

Permits HTML elements to be bound to external data sources in order to automate retrieval and update of information without requiring explicit action such as form submission.

Scriptlets

Encapsulated JavaScript that can be included in documents as an embedded object.

Modal Windows

The showModalDialog() and showModelessDialog() methods of Window permit the creation of special kinds of pop-up windows.

One of the more interesting features available as of IE4 is the ability to use scriptlets. Scriptlets are HTML documents embedded in the page with an <<object>> tag. Their purpose is to provide reusable functional units—for example, DHTML rollover effects or animation. The idea is to facilitate script reusability by encapsulating commonly used functionality in these components. Although scriptlet technology is interesting and often useful, it has been superseded in Internet Explorer 5 and later by a related technology, DHTML Behaviors, so we mention it only for historical perspective.

One lesser-known capability of IE4+ is the ability to disable instance properties for document objects. By setting the expando property of the Document object to false, any attempt to set instance properties in the document object hierarchy will throw an error.

Internet Explorer 5

Internet Explorer 5 provides even more features that make Web pages act more like applications than documents. A brief outline of some of these powerful features is found in Table 21-8.

Table 21-8: Some Proprietary Features Introduced in Internet Explorer 5

Feature

Description

HTML+TIME

The Timed Interactive Multimedia Extensions (TIME) is an XML-defined language providing synchronization of sound, video, and other effects in the page.

Dynamic Properties

Permits the assignment of an expression (rather than a static value) as the value of a property. These expressions are dynamically evaluated to reflect the current state of the page.

HTML Applications

HTML Applications (HTAs) are HTML pages (and associated scripts) run on the client as fully trusted applications. They are useful for writing code for Internet Explorer that is not subject to the usual security restrictions associated with untrusted code.

Attached DHTML Behaviors

A powerful technology that allows code performing some predefined action to be bound to tags in the page. Behaviors have a wide range of applications, from automatic modification of style to interacting with the user's browser in a manner similar to signed scripts in Netscape.

The HTML+TIME enhancement allows Web pages to become more centered on multimedia content. HTML+TIME provides advanced integration of text, images, audio, and video with HTML and permits synchronization of animation with other media elements on the page.

In addition to the major new technologies listed in Table 21-8, IE5 includes many proprietary improvements to the IE Document Object Model. It also includes changes to the IE Document Object Model to bring it partially in line with the W3C DOM. For example, the getElementById() and other basic DOM1 HTML methods are available, though this browser is not totally DOM1-compliant. See Chapter 10 for information about how to use these features.

Internet Explorer 5.5

Although one might expect a minor version like 5.5 to include relatively few new features, this is certainly not the case with IE5.5. Some major new proprietary functionality is listed in Table 21-9, but numerous “under the hood” improvements to object model and core language are included as well. Most noticeable are new DOM-compliant object model features and the adherence of JScript 5.5 to ECMAScript Edition 3.

Table 21-9: Some Proprietary Features Introduced in Internet Explorer 5.5

Feature

Description

Pop-up Windows

The ability to easily create highly customized pop-up windows.

Element DHTML Behaviors

An expanded version of the Attached DHTML Behaviors available in Internet Explorer 5.0. Element Behaviors allow you to define new elements with specific functionality that can be used like standard HTML in your pages.

Printing Customizations

Allows developers extreme flexibility with respect to how pages are printed from the browser, such as automatic document transformations to prepare it for printing, as well as the ability to define custom printing templates.

The ability to create customized pop-up windows simulates more complicated DHTML menu functionality, but with a much cleaner interface than most developers are used to. While this type of feature should be avoided by developers concerned with cross-browser compatibility, as more users switch to new versions of Internet Explorer, these kinds of pop-up windows will become an increasingly attractive alternative to more complicated DHTML solutions. Pop-up windows in IE5.5+ are discussed in a following section (and also in Chapter 12).

Internet Explorer 6

The major changes introduced by Internet Explorer 6 are standards-related. IE6 is almost CSS1 and DOM1 compliant, and has partial support for DOM2. The release of this browser at long last marked a convergence of Document Object Models among major browsers (Internet Explorer 6, Mozilla-based browsers, and Opera).

The browser’s emphasis on standards is highlighted by its two rendering modes: standards mode and quirks mode. By examining the document type definition statement (DOCTYPE) at the start of an (X)HTML document, the browser switches into one mode or another. Generally, standards mode is entered when an XHTML or fully qualified HTML DOCTYPE are encountered. The browser generally enters quirks mode when an older or unknown HTML DOCTYPE is encountered, and also if the DOCTYPE is missing. Visually, developers may notice slight layout changes between modes given the difference between layout models. Furthermore, JavaScript developers may notice that some proprietary features are absent in standards mode and that some tags or attributes may no longer be recognized causing extreme headaches. Always remember, correct JavaScript rests upon well-formed markup (not to be repetitious but you really need to know your (X)HTML to be a good JavaScript programmer).

Other improvements introduced in IE6 include the ability to capture mouse wheel events, support for P3P, improvements to the XML-handling capabilities (see Chapter 20), and various usability and multimedia (HTML+TIME) enhancements. A useful security feature for application developers is the ability to specify the security="restricted" attribute and value for <<frame>>s and <<iframe>>s. Using this attribute causes the document loaded in the frame to execute in the restricted browser security context (see Chapter 22), effectively disabling scripting and other kinds of potentially dangerous behavior.

Now that we’ve outlined the major proprietary features available in various versions of Internet Explorer, let’s examine some of them in a bit more detail.

CSS Filters

CSS Filters provide a way for developers to add a rich set of visual special effects to their pages without having to resort to embedded multimedia files (such as Flash). These capabilities are available as proprietary CSS (and JavaScript) extensions in systems capable of displaying 256 or more colors that are running IE4+. Filters change the static appearance of content in a way that is very similar to the filters provided by graphics manipulation programs such as Photoshop. Transitions provide movie-like special effects during page loads, for example, fade-ins and pixelations.

Filters and transitions can be applied to elements through scripts or through the use of static CSS. Specific properties for each filter and transition give the developer a wide range of flexibility over the nature of each effect. For example, they allow the specification of different colors, transition speeds, and even ambient lighting.

While full details of CSS Filters are beyond the scope of this book, the following example illustrates the use of the Xray filter. You can try it yourself by substituting your own image for “myimage.gif.” Clicking the image toggles the Xray filter.

<<script type="text/jscript">>
<<!--
function toggleXRay(theObject)
{
  // Get status of the filter
  var XRayStatus = theObject.filters.item('xray').enabled;
  // Toggle the status
  theObject.filters.item('xray').enabled = !XRayStatus
}
//-->>
<</script>>
<<!-- Place an image on the web page and manipulate the filter -->>
<<img src="myimage.gif" id="picture" style="filter:xray"
 onclick="toggleXRay(this);" />>

Using scripts to manipulate filters and transitions can give an almost film-like quality to a Web page. Instead of blasÚ rollovers from one image to another, JavaScript developers can use transitions such as fades, wipes, and dissolves to switch from one image to another.

You can find complete information about CSS Filters at MSDN, currently at msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/filters.asp (or simply search for microsoft css filters).

ActiveXObjects

Microsoft COM (Component Object Model) objects are reusable binary objects packaged for a specific task. Since many Windows applications are implemented as sets of cooperating COM objects, it’s often possible to reuse existing applications (or parts of existing applications) in the programs that you write. For example, you might use a COM object corresponding to Microsoft Word’s editing interface in order to implement text editing capabilities in your application.

JScript can access COM objects through ActiveX technology, a set of features enabling Web-based usage of COM. JScript uses an ActiveXObject to talk to an Automation server, basically, an object broker of sorts that implements one or more COM objects. Through the ActiveXObject you can instantiate COM objects to do various useful tasks. This ability gives JScript the power to do things “normal” applications can do by creating COM objects built for tasks like file I/O and Registry modification.

The basic syntax of COM object creation is

var comObj = new ActiveXObject("libraryname.typename");

The libraryname is the name of the library that implements the COM object typename. For example, to instantiate a Microsoft Word application that you could control with script you might use

<<script language="JScript">>
var wordObj = new ActiveXObject("Word.Application");
wordObj.application.visible = true;
<</script>>

This example creates a new Word window that can be completely controlled with script. The Word object exposes methods you can use to load, save, and modify documents. However, as we’ll see in a later section, not all COM objects you instantiate create separate applications.

Noteá

You can also pass classid values to the ActiveXObject constructor in order to create a specific object.

Two problematic questions are how to know what automation server and COM objects you can use, and how to know what methods such objects expose. The only good answer to these questions is to familiarize yourself with Microsoft COM and the objects typically available on most Windows machines. A discussion of these issues is well outside the scope of this book, but interested readers can find information on msdn.microsoft.com, or better yet, in any of the many good books on using Microsoft COM.

Security Issues

Security-conscious readers should be horrified at this point by the thought of JavaScript embedded in Web pages instantiating and controlling applications on the user’s machine. Scripts with this capability have carte blanche on the user’s machine: the ability to read and write files, perform network operations, and modify operating system settings. Clearly, the power of ActiveXControl should be restricted to those pages that can be trusted.

Because of the security risks associated with these tools, Internet Explorer only permits Web pages to instantiate COM objects marked “Safe for scripting” by their authors. This indicator is built into the object, and tells Internet Explorer that nothing “bad” can happen to the user’s machine if the object is controlled by script. Most powerful objects such as Word components and those that read and write from/to the file system are not marked safe for scripting, and thus cannot be instantiated by most Web pages.

The exception to this policy is pages loaded from Internet Explorer’s “Local Machine” and “Trusted Sites” security zones (see Chapter 22). Scripts loaded from these zones can instantiate unsafe controls, though typically doing so requires the user’s permission.

FileSystemObject

One of the more useful ActiveX controls you can instantiate is the FileSystemObject. It has automation server and type Scripting.FileSystemObject, and is, of course, not marked safe for scripting. The methods of this object are listed in Table 21-10.

Table 21-10: Methods of JScript’s FileSystemObject

Method

Description

BuildPath(path, name)

Adds the directory or file name to the end of the directory path given by path.

CopyFile(source, destination [, overwrite])

Copies the file source to destination, overwriting destination if the optional overwrite parameter is set
to true. You can use wildcards in source.

CopyFolder(source, destination [, overwrite])

Copies the directory source to destination, overwriting destination if the optional overwrite parameter is set
to true. You can use wildcards in source.

CreateFolder(folder)

Creates the directory specified by folder.

CreateTextFile(filename [, overwrite [, isUnicode]])

Creates the new text file filename, overwriting the existing file if overwrite is true. The file is created
as an ASCII text file unless isUnicode is true.

DeleteFile(filename [, force])

Removes the file filename. Will remove read-only files if
force is true.

DeleteFolder(filename [, force])

Removes the directory filename. Will remove read-only directories if force is true.

DriveExists(drive)

Returns a Boolean indicating whether the drive specified by drive exists.

FileExists(file)

Returns a Boolean indicating whether the file specified
by file exists.

FolderExists(folder)

Returns a Boolean indicating whether the directory specified by folder exists.

GetAbsolutePathName(path)

Returns the canonicalized directory path for path
(e.g., returns the absolute path if path is ..).

GetBaseName(path)

Returns the base name of the last component of path.

GetDrive(drive)

Returns a Drive object corresponding to the drive specified by drive.

GetDriveName(path)

Returns the name of the drive (if any) given in path.

GetExtensionName(path)

Returns the extension of the last component of path.

GetFile(filename)

Returns a File object corresponding to the file specified by filename.

GetFileName(path)

Returns the filename component of the given path.

GetFolder(folder)

Returns a Folder object corresponding to the directory specified by folder.

GetParentFolderName(path)

Returns the name of the folder that is the parent of the file or folder specified by path.

GetSpecialFolder(which)

Returns the name of the special folder given by which. The which parameter is an integer with values 0 (Windows folder), 1 (System folder), or 2 (Temporary folder).

GetTempName()

Returns a random filename (but doesn't create the file).

MoveFile(source, destination)

Moves the file specified by source to destination. Wildcards may be present in source.

MoveFolder(source, destination)

Moves the directory specified by source to destination. Wildcards may be present in source.

OpenTextFile(filename [, mode [, create [, format]]])

Opens the text file specified by filename. The mode parameter can be 1 (read only) or 8 (append). The Boolean create indicates whether the file should be created if it doesn't exist. The format parameter can
be 0 (use ASCII text), 1 (use Unicode), or 2 (use the system default).

While a complete discussion of this object is outside the scope of this book, you can see from the methods it provides that it enables you to do just about anything you’d like with the user’s filesystem. We’ll see a short example of these capabilities in the next section on HTML Applications.

HTML Applications

HTML Applications (HTAs) allow Web pages to be run like applications on a user’s machine. HTAs are normal HTML documents (with associated CSS and JavaScript) renamed with an “.hta” extension. When they are encountered on the Web, the user is prompted with the option to run the file like a normal executable or to save it to disk. Whether saved to disk and then activated or executed directly from the Web, the HTA runs within Internet Explorer. The appearance of the window in which the HTA appears is by default naked (without browser buttons, application menus, and so forth) but can be customized by placing an <<hta:application>> element in the document <<head>>.

The primary purpose of HTAs is to enable developers to implement complete applications with HTML and its associated technologies. The applications provide their own user interface and are given total access to the client machine. This means that you could write a word processor, spreadsheet, e-mail client, or file utility with an HTML- and CSS-based presentation that uses JavaScript to implement its functionality. You can embed Java applets and ActiveX controls in HTAs as you would in a normal page, and you can use these technologies to carry out operating system and network tasks that would be considerably more complicated or impossible with JavaScript alone.

The following example is a simple text editor. It reads and writes to a file called “test.txt” in the root directory of your C: drive. It doesn’t include any error checking and is only intended to demonstrate the basic operation of HTAs. The user is presented with a <<textarea>> and two buttons, one that writes the text to the file, and the other that reads the content of the file. You can save the following code as an .hta file and run it from your local drive or from a Web page. Before doing so, be sure that you don’t have any important information in C:\test.txt. The output (after typing in some extra text) is shown in Figure 21-2.

Click To expand
Figure 21-2: Using the FileSystemObject in an HTA to implement a simple text editor
<<html>>
<<head>>
<<title>>HTA Example<</title>>
<<!--  
Don't bother with XHTML as an HTA it buys you nothing and may cause problems  
-->>
<</head>>
<<script type="text/jscript">>
<<!--
// Careful -- no error checking
function readfile()
{
  var fso, filehandle, contents;
  fso = new ActiveXObject("Scripting.FileSystemObject");
  filehandle = fso.OpenTextFile("c:\\test.txt", 1);
  contents = filehandle.ReadAll();

  if (contents)
    document.all("filecontents").value = contents;

  filehandle.Close();
}

function writefile()
{
   var fso, filehandle;
   fso = new ActiveXObject("Scripting.FileSystemObject");
   filehandle = fso.CreateTextFile("c:\\test.txt", true);
   filehandle.Write(document.all("filecontents").value);
   filehandle.Close();
}
//-->>
<</script>>
<</head>>
<<body onload="writefile();">>
<<h2>>Simple File Editor<</h2>> Modifying <<tt>>c:\test.txt<</tt>>
<<form>>
<<textarea id="filecontents" cols="50" rows="15">>
HTAs are powerful.
<</textarea>>
<<br>>
<<input type="button" value="Read file" onclick="readfile();">> &nbsp; &nbsp;
<<input type="button" value="Write file" onclick="writefile();">>
<</body>>
<</html>>

There are some significant drawbacks to using HTAs. First, they work only under IE5+ in Windows systems. Second, because they are allowed unfettered access to local operating system resources, many users will (for good reason) be reluctant to run them. Note that the browser does warn about HTAs before they are run, as shown here:

Click To expand

Despite the fact that the ActiveX controls embedded in many pages users visit on a regular basis have the same capabilities, many users are reluctant to run “executables” like HTAs, even if they can view the source beforehand. There are also some special considerations when using frames with HTAs.

Data Binding

Server-side programs such as CGI scripts have traditionally been used to implement data-intensive Web applications, such as pages that allow a user to query or update a large database of information. In the traditional model, form data is submitted to a server-side program, which then parses it, queries the relevant data source, and builds a new page from the result of the query. This new page is then returned to the client, and the process begins anew. Data Binding in Internet Explorer 4+ shifts most of the work to the client side by providing the ability to bind data sources directly to markup elements.

In the Data Binding model, a data source is defined at the beginning of the page and then bound to elements (such as <<span>>s in a table or form fields) with the proprietary datasrc and datafld attributes. Through an embedded applet or ActiveX control, the browser automatically handles the retrieval, organization, and presentation of data in the page, a responsibility that was once the domain of server-side scripts. By moving functionality from the server to the client, any further processing of the data—for example, refining search criteria or re-ordering data items—can be carried out in the browser without additional interaction with the server. A wide variety of data sources (Data Source Objects, or DSOs in Microsoft parlance) can be used to supply the data in a fairly interchangeable manner. Most often these DSOs are SQL databases, but they can also be JDBC data sources or even XML or tab-delimited text files.

To better understand the idea of data binding, let’s present a simple example. In this case we use an external data file containing two or more columns of comma-delimited data. The first line contains the names of the data set fields corresponding to the columns. The following lines contain the actual data for the appropriate fields. The sample external data file called “alphabet.txt” is shown here:

Letter, Thing
A, Apple
B, Boy
C, Cat
D, Dog
E, Elephant
F, Fox
G, Girl
H, Hat

To access the data, an HTML document references an object for a data source control and a related table definition. The following is an example of how this would be accomplished:

<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<<html xmlns="http://www.w3.org/1999/xhtml">>
<<head>>
<<title>>Data Binding Example<</title>>
<<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />>
<<!--   validation not possible due to datasrc and datfld attributes -->>
<</head>>
<<body>>
<<object id="alphabet" 
classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83">>
    <<param name="DataURL" value="alphabet.txt" />>
    <<param name="UseHeader" value="True" />>
<</object>>

<<table datasrc="#alphabet" border="1">>
<<thead>>
    <<tr bgcolor="yellow">>
        <<th>>Letter<</th>>
        <<th>>Reminder<</th>>
    <</tr>>
<</thead>>
<<tbody>>
    <<tr align="center">>
        <<td>><<span datafld="Letter">><</span>> <</td>>
        <<td>><<span datafld="Thing">><</span>><</td>>
    <</tr>>
<</tbody>>
<</table>>
<</body>>
<</html>>

This HTML code generates a table from the file “alphabet.txt” in which each table row contains a letter of the alphabet and the name of a thing that can remind the reader of that letter. The rendering of this example under Internet Explorer is shown in Figure 21-3.


Figure 21-3: Data Binding example under Internet Explorer

While a complete discussion of Data Binding is outside the scope of this book, JavaScript programmers in an Internet Explorer environment should be aware that the browser provides a very powerful set of features related to Data Binding. These features are exposed through the Document Object Model, most obviously as the dataSrc and dataFld properties of element objects as seen in the last example. You can dynamically add, modify, and delete data sources from different tags in addition to directly accessing and manipulating the data records themselves. Data source objects have a recordset property that can be used to move through, add, and modify records dynamically. Often developers present the user with a list of records and use the recordset methods to display and change individual records in response to user actions, for example, by including calls to recordset methods in onclick handler of form buttons.

Dynamic Properties

In Internet Explorer 5+, the value of a property is not restricted to a static value. You can set a property equal to any valid JavaScript expression, causing the value to be updated whenever the value of the expression changes. The methods used for dynamic properties are listed in Table 21-11. The first three can be invoked as methods of any object in the document object hierarchy, while the recalc() method is a property of the Document object.

Table 21-11: Methods Used with Dynamic Properties in Internet Explorer 5+

Method

Description

setExpression("aproperty", "expression")

Sets the aproperty property of the object to expression.

getExpression("aproperty")

Retrieves the expression to which the value of aproperty is set.

removeExpression("aproperty")

Removes the expression to which the value of aproperty is set.

document.recalc(allExpressions)

Explicitly forces recalculation of properties set to expressions for the document. allExpressions is a Boolean that when true, forces recalculation of every expression in the document. If false or omitted, only those expressions that have changed since the last recalculation are reevaluated.

The most obvious application of dynamic properties is to automate style updates, eliminating the need to manually update styles when an event like window resizing occurs. For example, to automatically scale a heading’s font size with the window size you might use

<<h1 style="position: absolute; font-size: 48pt;"
 id="myHeading">>Dynamic Properties<</h1>>
<<script type="text/jscript">>
<<!--
document.all("myHeading").style.setExpression("fontSize",
             "document.body.clientWidth/6");
//-->>
<</script>>

The result before resizing and after resizing is shown in Figure 21-4.

Click To expand
Figure 21-4: Dynamic properties let you automate style calculations.
Noteá

You can set dynamic properties directly in style sheets using the expression() syntax—for example: height: expression(document.body.clientHeight/2).

Dynamic properties are, of course, not limited merely to style. The following example illustrates the automatic updating of the innerText property of an element. The sum element’s innerText property is set to an expression summing the values of two form fields. Whenever the values of fields change, the sum is updated. Sample output is shown in Figure 21-5.

Click To expand
Figure 21-5: Using dynamic properties to create a basic calculator
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<<html xmlns="http://www.w3.org/1999/xhtml">>
<<head>>
<<title>>Dynamic Properties Example 2<</title>>
<<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />>
<</head>>
<<body>>

<<form action="#" method="get">>
First Number: <<input type="text" id="num1" value="0" />><<br />>
Second Number: <<input type="text" id="num2" value="0" />><<br />>
Sum: <<b id="sum">> <</b>>
<</form>>
<<script type="text/jscript">>
<<!--
// We could get into trouble if the value of the text fields aren't
// numbers, so we assume that a non-integer value means zero.

function computeSum() 
{
  var n1 = parseInt(document.all("num1").value);
  if (!isFinite(n1))
    n1 = 0;
  var n2 = parseInt(document.all("num2").value);
  if (!isFinite(n2))
    n2 = 0;
  return n1 + n2;
}
document.all("sum").setExpression("innerText", "computeSum()");
// -->>
<</script>>
<</body>>
<</html>>

Many developers find the dynamic properties capability very exciting. It simplifies some aspects of page layout and can be used to implement all sorts of applications. The simple calculator capabilities hinted at in the previous example are just the tip of the iceberg.

DHTML Behaviors

Behaviors are aimed at moving complex DHTML code out of the page and into smaller, encapsulated, reusable units that serve as the basic building blocks for more complicated applications. Behaviors are a natural outgrowth of the scriptlet capabilities included as a part of Internet Explorer 4. The idea is to encapsulate specific functionality—for example, rollover image swapping or tooltip display—in an HTML Component (HTC) that can be bound to arbitrary elements in a page. HTCs are just separate files containing instance-independent JavaScript code, but in principle Behaviors can be implemented as binaries or VBScript just as easily. However, because this is a book about JavaScript, we naturally focus on HTCs using Microsoft’s form of JavaScript, JScript.

At first glance, the task of moving DHTML code out of the page itself might seem daunting. After all, it always seems there needs to be some JavaScript in the page, doesn’t it? The truth of the matter is that Behaviors allow you (in principle) to move all DHTML code, including event handlers, outside of the main document. While there are certainly cases where you will want to include JavaScript directly in the page, you can move most commonly used functionality into HTCs. Customization of Behaviors attached to individual elements is achieved by including an appropriate developer-defined HTML attribute in their tags. Additionally, Internet Explorer comes equipped with numerous and powerful built-in Behaviors that you can use without any coding at all. And, to top it all off, binding Behaviors to elements is incredibly simple. A Behavior can be attached to an element with only one line of JavaScript, or with no JavaScript at all by using an element’s CSS bindings.

Excluding scriptlets, there are two kinds of Behaviors available. Internet Explorer 5 supports the original DHTML Behaviors, now referred to as “attached Behaviors.” Internet Explorer 5.5 supports an extension of attached Behaviors known as “element Behaviors.” The two technologies are not mutually exclusive; rather, each complements the capabilities of the other. The following sections focus primarily on attached Behaviors, but we include a brief discussion of element Behaviors toward the end.

Attaching Behaviors

There are several ways to add a Behavior to an element. The first is by using an object’s addBehavior() method. This method accepts a string as an argument indicating the URL of the HTC file that defines the Behavior to add. For example, to attach a rollover Behavior defined in “rollover.htc” to a button with id “myButton,” you might write

document.all("myButton").addBehavior("rollover.htc");

You can achieve the same result by setting the behavior property of the object’s Style.

For example:

document.all("myButton").style.behavior = "rollover.htc";

Normally, when binding Behaviors to a large number of elements, the behavior extension to the CSS syntax is used. For example, you might assign all your rollover buttons to class “rolloverButton” and then attach the HTC to the class with the following CSS:

.rolloverButton { behavior:url(rollover.htc) }

Because Behaviors are an extension to CSS, you can define them inline as well:

<<img style="behavior:url(rollover.htc)" src="myimage.gif" />>

To add multiple Behaviors to an element, you can use multiple calls to addBehavior(), set multiple space-separated values in the assignment to style.behavior, or include multiple url() clauses in the style sheet. The following example illustrates the use of multiple url()s in the style bindings:

.rolloverButton { behavior:url(rollover.htc) url(tooltip.htc) }

Removing Behaviors

The process of removing a Behavior depends upon how it was added. If the Behavior was added using addBehavior(), then the return value of this method is a unique integer that can be passed to removeBehavior() in order to remove it. If the Behavior was added using another method, removing it is considerably more complicated. You will most likely need to manually examine the behaviorUrns[] collection of the element in question to determine the id of the Behavior you wish to remove. Once determined, you might be able to pass that integer to removeBehavior(). A simple example of adding and then immediately removing a Behavior follows.

var behaviorIndex = document.all("myButton").addBehavior("rollover.htc");
document.all("myButton").removeBehavior(behaviorIndex);

If you need to dynamically remove Behaviors, it is almost always best to add them with calls to addBehavior() rather than inline CSS.

Defining Behaviors

HTC files define the public interface, event bindings, and code for a Behavior. These files contain HTML and HTC elements and are saved with an .htc extension. The following example shows the form of a typical HTC file:

<<public:component>> 
   <<!-- definitions of public properties -->>
   <<!-- definition of public methods -->>
   <<!-- definitions binding events at the element to actions in this HTC -->>
<<script type="text/jscript">>
  // Code implementing HTC behavior
<</script>>
<</public:component>>

The <<public:component>> and related elements are defined by the proprietary XML-based HTC language, so don’t worry if you haven’t seen them before. You will also notice that some elements will be closed with />>. Doing this ensures that empty elements are well formed, as required by XML.

Ignoring for the moment the issue of public methods and properties, we first consider how to bind events to code in the HTC. Event binding is carried out with the <<public:attach>> element. Its event attribute is set to the event handler you wish to “capture,” and its onevent attribute is set to the code to execute when the event occurs. For example, to capture mouseover events and change the background color of the element, you might define the following HTC:

<<public:component>> 
<<public:attach event="onmouseover" onevent="activateBackground()" />>
<<script type="text/jscript">>
<<!--
var originalColor;
function activateBackground() 
{
  originalColor = style.backgroundColor;
  style.backgroundColor = "yellow";
}
//-->>
<</script>>
<</public:component>>

Notice how the HTC can implicitly access the Style object of the element to which it is bound. This is because the scoping rules for HTCs dictate that, if the identifier is not found in the Behavior itself, then the element to which it is attached is the next enclosing scope. If the name cannot be resolved in the element to which it is attached, the Window in which the element is defined is checked. Note that you can reference the object to which the Behavior is bound explicitly using the element identifier, but there is rarely a need to do so in practice.

To expose a public property to the document containing the element to which the Behavior is bound, a <<public:property>> element is used with the name attribute set to the name of the property. For example, you might include the following in your HTC:

<<public:property name="activeColor" />>

Elements to which the Behavior is bound can then set this value by setting an activeColor attribute. Assuming the “rollover” class is bound to your HTC, you might use

<<a href="index.html" class="rollover" activeColor="red">>Click me<</a>>

To see how this might be used, we revisit the previous rollover example, this time including an onload event handler that sets the activeColor if one was not defined in the element:

<<public:component>>
<<public:attach event="onmouseover" onevent="activateBackground()" />>
<<public:attach event="onmouseout" onevent="deactivateBackground()" />>
<<public:attach event="onload" for="window" onevent="initialize()" />>
<<public:property name="activeColor" />>
<<script type="text/jscript">>
<<!--
var originalColor;
function activateBackground()
{
  originalColor = style.backgroundColor;
  style.backgroundColor = activeColor;
}
function deactivateBackground()
{
  style.backgroundColor = originalColor;
}
function initialize()
{  
  // If the activecolor wasn't specified in an attribute, set it
  if (!activeColor)
    activeColor = "yellow";
}
//-->>
<</script>>
<</public:component>>

There are several new aspects to this HTC. An onmouseout handler was attached to revert the background to its original color. In addition, the activeColor property was exposed, allowing it to be set as an element’s attribute. An onload handler for the Window object was also specified. This handler invokes initialize(), which checks to see if the activeColor was specified in the element to which the Behavior is attached. If it wasn’t, activeColor will not be defined, so it is set to a default value, in this case yellow.

Assuming that this Behavior is included in the file “rollover.htc,” we can attach it to elements in a document; for example:

<<b style="behavior:url(rollover.htc)" activeColor="red">>This is red on
rollover<</b>>
<<br />>
<<b style="behavior:url(rollover.htc)">>This is yellow on rollover<</b>>

The first <<b>> has an explicitly set activeColor, but the second does not. As a result, the second receives the default color, yellow.

HTCs can expose methods as well as properties. Exposing a method is similar to exposing a property, except that a <<public:method>> element is used with name set to the name of the function to expose. Once exposed, the function can be invoked as a method of any element to which the Behavior is bound.

Although the capabilities we have discussed so far might seem impressive, they are really only the basic aspects of Behavior definition. There are numerous other features available, including the ability to create custom event handlers and much nicer DHTML effects than we have space for here. After reading this section, you have a solid grounding upon which you can build more advanced DHTML Behavior skills. Interested readers are encouraged to visit Microsoft’s MSDN site (msdn.microsoft.com) to learn more about what DHTML Behaviors have to offer. But first, it is important to acknowledge that writing your own Behavior may not be necessary as there are many Behaviors that come built into the browser by default.

Default Behaviors

Internet Explorer 5+ comes equipped with numerous DHTML Behaviors that can be applied to a wide variety of elements. These Behaviors are listed in Table 21-12.

Table 21-12: Some Default Behaviors Available in Internet Explorer 5+

Behavior

Description

>anchorClick

Enables the browser to show a browseable navigation “tree” for a Web server. This Behavior can only be attached to <a> elements.

>Anim

Enables interaction with Microsoft's DirectAnimation viewer.

>clientCaps

Provides information about the browser and platform—similar to Navigator object, but more detailed. Also provides an easy way to install browser components.

>Download

Downloads a file and invokes a callback function when the download has completed.

>homePage

Provides information about the user's starting page. For example, it permits getting, setting, and navigating to the start page.

>httpFolder

Enables features that allow browsing of navigation “tree” (folder view).

>saveFavorite

Enables the current state of the page to be saved when the page is added to the user's list of “Favorites.” Most often attached to a form and very useful for a “login” page.

>saveHistory

Enables the current state of the page to be saved for the current browsing session. Whenever the user navigates back to the page, the page will be displayed with the saved state. Most often attached to a form.

>saveSnapshot

Enables the current state of the page to be saved when the user saves the page to the local file system.

>userData

Permits saving and retrieving large amounts of state information, even across multiple browsing sessions.

As you can see, the default Behaviors are more related to browser functionality and state information than to traditional DHTML. The interfaces they expose can be a bit complex, so we will not get into the specifics of each (although an example of saving state information is included at the end of Chapter 16, and browser capabilities were touched upon in Chapter 17).

Default Behaviors are attached to elements like any other Behavior, but the URL employed has the form

#default#behaviorName

where behaviorName is the name of the default Behavior you wish to attach. For example, to attach the userData Behavior to all form elements, you might use the following in your CSS definitions:

form { behavior:url(#default#userData) }

Full documentation of default Behaviors can be found at MSDN.

Element Behaviors

Whereas attached Behaviors augment or override the normal behavior of an existing element, element Behaviors are used to define new, customized elements. For instance, you can create your own rollover element, define default Behaviors for it, and include it in your pages as if it were a real part of HTML. You can even use attached Behaviors with new elements created in this fashion.

Creating a custom element is like creating an attached Behavior. An HTC file is created using almost exactly the same syntax as you would use to define an attached Behavior. However, an element Behavior is imported into the page using XML, and after it has been imported, the new element can be used directly in the page without explicit binding to the HTC file. Because the HTC file defines the new element, there is no need to use addBehavior() or the CSS syntax used for attached Behaviors; doing so would be redundant. In fact, it is not possible to bind an element Behavior to an element as you would an attached Behavior.

Element Behaviors are tremendously powerful, and well beyond the scope of this book. However, readers with an understanding of XML and the attached Behavior features discussed previously should have little problem creating their own elements. Aside from the highly nonstandard nature of element Behaviors, the only drawback of their use is that they are supported only by Internet Explorer 5.5+. For the time being, it might be advisable to stick with attached Behaviors until browser demographics shift heavily to newer versions of IE.

Behaviors Versus Traditional DHTML

There are two primary advantages that attached Behaviors have over traditional DHTML. The first is that attached Behaviors are easier to add to your pages and are easier to maintain once they have been added. The second is that Behaviors are more encapsulated and reusable than most traditional DHTML applications. While traditional DHTML can certainly be written in a very modular fashion, it is generally easier to create reusable components using attached Behaviors. In addition, Behaviors are easily used in combination on the same element. This is a feature even well-written traditional code often lacks.

Element Behaviors permit functionality that would otherwise be impossible (or very hard to obtain). The ability to extend your documents with your own custom elements gives you freedom in design and implementation.

The downside of Behaviors has already been mentioned, namely, that they are a proprietary technology not yet a part of any standard. But, then again, a large number of DHTML applications are written to use proprietary Document Object Models, so Behaviors do not mark all that significant of a departure from traditional trends.

Pop-up Windows

Internet Explorer provides the ability to create pop-up windows using the createPopup() method of the Window object. This capability was touched upon in Chapter 12, but is included here for completeness.

The behavior of pop-up windows is different than that of windows created with window.open(). The createPopup() method accepts no arguments and returns a reference to a window that was created. The newly created pop-up window is initially empty and hidden and is not immediately given focus. The programmer is responsible for populating the window with content and then displaying it to the user with its show() method. The pop-up menu is then automatically hidden once the user activates another part of the page, for example, by right-clicking outside of the pop-up menu.

The syntax of the show() method is

popupWindow.show(x, y, width, height [, relativeTo])

where popupWindow is a reference to a window created with window.createPopup() and x, y, width, and height specify the horizontal location, vertical location, width, and height of the pop-up window in pixels. The optional relativeTo parameter is a reference to the object to which the x and y coordinates are relative. If relativeTo is omitted then the x and y coordinates are treated as relative to the upper-left corner of the main window.

Creating an example pop-up window gives us a good excuse to exercise the conditional compilation features mentioned earlier in the chapter. Because pop-up windows are available only in Internet Explorer 5.5+, one would only be used if supported by the browser. Otherwise, an alert() box would be used, although it would probably be better to use a relatively positioned DHTML layer in a “real” application. The pop-up menu displayed in IE5.5 is shown in Figure 21-6.

Click To expand
Figure 21-6: Pop-up windows give you different behavior than alert()s or regular browser windows.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<<html xmlns="http://www.w3.org/1999/xhtml">>
<<head>>
<<title>>Popup Window Example<</title>>
<<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />>
<<script type="text/javascript">>
<<!--
function showPopup()
{
   /*@cc_on @*/
   /*@if (@_jscript_version >>= 5.5)
       var newpopup = window.createPopup();

       newpopup.document.body.style.backgroundColor = "lightblue";
       newpopup.document.body.style.padding = "8";
       newpopup.document.body.innerHTML = "What a <<b>>wonderful<</b>> window!";
       newpopup.show(150, 300, 150, 50, document.all("mybutton"));
    @else @*/
       alert("What a boring window!");
   /*@end @*/
}
// -->>
<</script>>
<</head>>
<<body>>
<<h2>>Popup Example<</h2>>
<<form action="#" method="get">>
  <<input id="mybutton" type="button" value="Show the popup" onclick="showPopup();"
 />>
<</form>>
<</body>>
<</html>>

The pop-up window has a few other useful properties besides show(). Its hide() method hides it from view and its isOpen property returns a Boolean indicating whether the window is currently displayed. A few more examples of IE-specific window features can be found at the end of Chapter 12 and, of course, online at MSDN.

Other JScript Capabilities

There are numerous JScript capabilities that you might not be aware of. Listed here are some of the most interesting applications and tools that Microsoft provides for JScript. Learn more about these technologies at http://msdn.microsoft.com/scripting.

  • Remote Scripting Permits remote procedure calls (RPCs) from client-side JScript to server-side JScript in both a synchronous and asynchronous fashion. Client-side scripts make calls through an embedded Java applet to Active Server Pages on the remote server, eliminating the need for traditional interaction via the submission of form data. You can see examples of similar features in Chapter 19.

  • Script Control Allows you to embed JScript and ActiveX controls in applications.

  • Script Host Integrates JScript support into the Windows operating system, allowing you to automate OS tasks with JScript in a manner similar to shell scripting in UNIX.


Team LiB
Previous Section Next Section