Dynamic HTML:The Definitive Reference (2nd) Support Center

Download

Save your carpal tunnels: Download the examples files from the O'Reilly site.

Corrections & Updates

  • Page 63. In the style element code near the bottom of the page, the second rule should be:
       p:firstline {font-variant:small-caps}
  • Page 89-93 (DHTML API Listing). Unfortunately, Apple's Safari browser (including release 1.2) does not support the W3C DOM document.defaultView.getComputedStyle() method to facilitate reading the effective style of an element. This screws up some of the API functions in that browser. The quick fix is to modify each line of the getObjectLeft() and getObjectTop() functions that currently read:
       if (document.defaultView) {
    to:
       if (document.defaultView && document.defaultView.getComputedStyle) {
    This forces Safari to use the elem.style.left and elem.style.top properties -- not ideal for a W3C DOM browser, but it seems to do the job.
  • Page 90. The very first code line on the page should be:
       theObj = seekLayer(doc.layers[i].document, name);
  • Page 102. In Example 5-1, the document.write() method argument has an extra quote that doesn't belong. The statement should be:
       document.write(navigator.userAgent + ".");
  • Page 102. The fourth line from the bottom of Example 5-2 shows an uppercase close tag at the end of the line. It should be: </p>.
  • Page 142. The last text range example (Turning a user selection into a text range) is missing a set of empty parentheses in the Netscape code. The statement should read:
       var rangeRef = window.getSelection().getRangeAt(0);
  • Pages 163-4. The discussion about the event.returnValue property in IE incorrectly indicates that the property returns true by default. This is not correct (despite Microsoft's claims to the contrary). In fact, this is one of the oddest object properties in the entire IE DOM in that its default value is undefined. What's so weird about this is that I know of no other object that enumerates an undefined property (i.e., you can use for-in introspection of the object to uncover the returnValue property whose value shows up as undefined). Normally, an undefined property doesn't show up in the enumeration because the property is, well, undefined, as in "doesn't exist."

    In the numberPlease() function at the bottom of page 164, the most deeply nested group of if conditions is predicated on the returnValue property returning true by default. Since that is never the case, the first if branch never executes. There is no way (that I know of) to find out if the current browser supports the property because any property detection scheme is immediately defeated by the property's default value (sigh).

    Therefore, the solution is to set the property whether or not it's there:
        if (evt.preventDefault) {
            evt.preventDefault();
        else {
            evt.returnValue = false;
            return false;
        }

    It's redundant to include the return false statement for browsers that support returnValue, but it covers the older browsers, as well, without conflicting with IE5 and later.

  • Page 209. Another constant value for the target attribute is _content, which works in Netscape 6+ for links in a sidebar that change the page in the main content area.
  • Page 265. While in theory you should be able to specify the <?xml> declaration at the top of an XHTML document, IE6 unfortunately interprets this as a switch to go back to quirks (backward-compatible) CSS mode, no matter what DTD you point to in the <!DOCTYPE> declaration. To validate your pages completely with the W3C XHTML validators, include your character set in a meta tag, like this:
       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  • Page 304. The xmlns attribute has two possible assignment operators, depending upon its usage. The equal sign (=) is used to assign a namespace specification (typically a URI) to a default namespace to be used by the current element and any of its child elements. The colon (:) is used to assign a namespace specification (URI) to a namespace prefix (so that the prefix acts like a shortcut namespace reference when used to denote attributes belonging to a particular namespace).

    A common example is the you can use in an XHTML document to signify that the document is to use -- by default -- the W3C XHTML DTD as the source of meaning for elements and attributes in the rest of the document:
       <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    Namespace prefixes are used (primarily in XML documents) when you have a mixture of DTDs from multiple sources governing the element and attribute rules of the document. For example:
       <html xmlns:au="http://www.writers.org/2002/author-guidelines">
    Once the au prefix is assigned, it can be used in other elements within the scope of the <html> element to signify an attribute defined by the DTD associated with the namespace URI (theoretically allowing the "custom" attribute to validate correctly):
       <p au:license="Creative Commons">...</p>
    Internet Explorer (at least for Windows) appears to have some additional namespace prefixes built into it. Thus the example shown in the book (xmlns:MSIE). I haven't yet found a sufficient explanation about what they are or when you'd use them.

  • Page 306.Details about the allowtransparency attribute of the <iframe> tag were inadvertently omitted. The attribute is available in IE 5.5 or later and controls whether the background plane of the iframe element is transparent or opaque. To allow the main document to show through the iframe, set the allowtransparency attribute to true and either leave the iframe's background-color style property at its default setting (transparent) or set it explicitly to transparent. Note that this transparency affects the iframe element, independent of any document loaded into the iframe. Therefore, if you want a background style to affect only the iframe, you must set the allowtransparency attribute of the iframe to true and set the background of the element that appears behind any document loaded into the iframe (provided the document's background is transparent). An allowtransparency attribute setting of false (the default) does not allow background styles associated with the iframe element to be visible (but background styles in the iframe's nested document will be visible).
  • Page 358. Netscape 4 does appear to support the href attribute for the <link> tag. The Netscape engineers never documented it, which I frequently interpret to mean that while they may have implemented the attribute, they don't guarantee it. But a report from the field indicates reliable support for a variety of NN4.xx generations.
  • Pages 363-369. Mozilla added some support for the Microsoft <marquee> tag at the last minute before the Netscape 7 release (I was working with the Mozilla 1.0 branch, and Netscape 7 was eventually built from the Mozilla 1.0.1 branch, which arose after the book went to bed). Including this non-W3C element was bitterly contested until the end, but because some important sites (mostly in Asia) used the element for mission-critical data presentation, marketing won the religious war.

    The element is implemented internally not as a separate element, but as a div element associated with an internal style sheet definition that governs the behavior of the element (via Mozilla's XBL mechanism for customizing the engine). In one sense, then, the object model remains pure, because there is no dedicated HTMLMarqueeElement node in the model -- just a div that accrues some special properties and methods.

    Now, as to what is and isn't supported. The following element attributes (and corresponding scriptable properties) are available:

    AttributePropertyNotes
    behaviorbehaviorOnly supported value is alternate
    bgcolorbgColorIn Windows only
    directiondirectionSame values as IE
    scrollamountscrollAmountSame values as IE
    scrolldelayscrollDelaySame values as IE
    widthwidthBut not height (yet)

    Even in Mozilla 1.2, there were still plenty of bugs in the element's behavior. Basic marquee stuff works OK, especially in horizontal scrolling. For scripting purposes, the start() and stop() methods work. The Netscape element does not fire any events.

    There you have it. Use it at your own peril. And please don't send me the URLs where you've implemented this element. I object on aesthetic (not religious) grounds.

  • Page 402. The last line of the Example section has a typo for the src attribute name.
  • Pages 410-11. The last sentence of the multiple attribute of the select element needs some clarification. Turning on this attribute for an element whose size attribute is 1 does have an effect in IE5 or later (Windows only) and recent Mozilla-based browsers. The effect is particularly useful in IE, where the result is a one-line, non-popup list control (sometimes called a spinbox). Recent Mozilla versions also do this, but the button controls can be funky. IE for the Mac (and Safari betas, for those who want to know) automatically expand the dimensions of the select element to a default height of four rows when you turn on multiple.

    Similarly, the discussion of the size attribute on page 411 should be colored with this information with respect to a value of 1.

  • Page 418. I've been alerted that my code example for the <sub> tag is correct, but my chemistry is all wrong. That's what I get for trying to do something other than the classic water formula. The formula H3O apparently represents a hydronium ion.
  • Page 490. A sin of omission on my part for failing to report a more egregious (IMHO) sin of omission on Microsoft's part: In IE for Windows, the innerHTML property is read-only for the following elements: col, colgroup, frameset, html, style, table, tbody, tfoot, thead, title, tr.
  • Page 521. Compatibility for the normalize() method should include IE6(Win) and IE5(Mac). Be aware, however, that the method does not work correctly in IE6, and one reader avoids it because it crashes his IE6. I don't have problems in MacIE5, however, and the method is supported in Safari 1.2.

  • Page 574. Missing from the document.body listings is the createControlRange() method. Supported in IE 5 or later for Windows, this method returns a controlRange object (collection). The initial object is an empty collection to which you can add arbitrary elements (via the addElement() method). Once you have gathered the desired selection of elements, you may then invoke one or more of the IE commands (see Appendix D) through the execCommand() mechanism. As you can see, a controlRange is like an element-oriented version of a TextRange. I have yet to find a truly useful example of why I'd use this object except when in content editing mode. One article somewhere suggests using it to script copying an image to the Clipboard. Well, OK, maybe somebody wants to do that.
  • Page 584. The clipboardData object does use the Windows system clipboard.
  • Page 669. The default value of IE's event.returnValue property is undefined. See the discussion for Pages 163-4 for more about this anomaly.
  • Page 818. The last sentence of the description of the object property should read: The object property wrapper tells the JavaScript interpreter to access the property of the external object loaded into the element, and not the property of the HTML element itself.
  • Page 824. The length property of the options object is not just "read-only," as you can see from the example on page 821. You can assign a value of zero to this property to empty out a select element's options prior to assembling a new set.
  • Page 866. In the add() method of the select element, the IE-only positionIndex parameter can also be a value of -1 to signify that the new option element should be appended to the end of the current list of options. This simplifies attempts at making a cross-DOM function to append new options to a select element, as in this script fragment:
       var where = (navigator.appName == "Microsoft Internet Explorer") ? -1 : null;
       ...
       var newElem = document.createElement("option");
       newElem.text = "Red:";
       newElem.value = "#ff0000";
       mySelect.add(newElem, where);
  • Page 960. The second paragraph of the TextRange description incorrectly suggests you can assign a value a range's htmlText property. This is a read-only property, as mentioned on p.962. To assign some HTML to the range, use the TextRange.pasteHTML() method.
  • Page 976. The last paragraph of the TreeWalker object description has a typo in the third line. The fifth full word should be position.
  • Page 995. The next-to-last word of the description for the scrollX and scrollY properties should be in monofont: html.
  • Pages 1006-1007. Compatibility ratings for window.resizeBy() and window.resizeTo() indicate that the methods don't work in Netscape browsers past version 4. The methods do work in NN7 and Mozilla/Firefox browers, but not on the Macintosh platform. I've also heard that Windows XP SP2 causes problems with the resize methods in IE6. Any further reports on this are welcome.
  • Page 1023. The oncontextmenu event is implemented in Netscape 6 and later (although it's not a W3C DOM Level 2 event). It even works in the Mac version, where the event fires when the user clicks and holds the mouse button atop an element. An unexpected surprise.
  • Pages 1011-12. I pass along this tidbit I first saw on thelist: The Microsoft proprietary window.showModalDialog() method has a quirk in IE/Macintosh. You must specify window dimensions of 201 pixels or greater. Values below that threshold force the window to open at a default, rather large size.
  • Pages 1022. Everyone and their mothers know that the onchange event fires in a select element just by choosing a different option (except in NN2 for Windows). For all but that wayward early browser, the event does not fire when the select element loses focus.
  • Pages 1029. The first two sentences of the onkeypress event discussion should read: "Fires when the user presses a keyboard character key or holds it down until the computer's auto-repeat mechanism takes hold. During auto-repeat, a new event fires prior to each character registering with the system (e.g., for display in a text box). The event sequence is: onkeydown, onkeypress, and onkeyup." For text fields, the onkeypress event fires before the typed character appears in the text box. Therefore, the value of the event target/srcElement has the text prior to the addition of the typed character.
  • Page 1039. At the top of the page, the discussion about relative URLs in CSS rules should be clarified. Per the W3C spec, relative URLs in CSS rules are relative to the location of the document housing the CSS rule. For CSS rules embedded within the page (e.g., literal rules in a document's <style> tag or assigned to an element's style attribute), relative URLs are relative to the current HTML document. But for an imported .css file, a relative URL is relative to wherever the .css file lives (e.g., such as in a css subdirectory).
  • Pages 1064-5. My personal saga of the display CSS property's compatibility with NN4 continues. Contrary to a previous errata note in this place, NN4 does support the none, block, and inline settings. It still holds true, however, that the property is not scriptable in NN4. The property value guide on page 1065 should list 4 under the NN column for those three display types.
  • Pages 1116. The example for vertical-align should read:
       span.sup {vertical-align: super: font-size: smaller}
  • Page 1131. For the Array.push() method, the returned value is the length (integer) of the array after appending the newest item(s).
  • Page 1149. The first line of the example for the message property should read:
       if (myError.message.indexOf("defined") != -1) {
  • Pages 1167. To be consistent with the description, the first formula for the Math.random() method should read:
       Math.floor(Math.random() * (n + 1))
  • Pages 1174-1180. Let me clarify some things about the multiline property and what the whole "multiline" thing means in JavaScript regular expressions.

    Although Netscape 4+ implements a multiline property for the RegExp static object, that is not normal, and is not supported elsewhere. Such a property is not part of the ECMA standard. The only place the property should be read is from an instance of a RegExp object. That property is missing from the regular expression property descriptions on pages 1178 and 1179.

    The value of the regexp's multiline property is determined exclusively by the presence or absence of the 'm' flag in the object constructor (it's another flag just like the 'g' and 'i' flags). In other words, the scripter determines whether the multiline property of the regexp object will be true by explicitly setting the 'm' flag, as in:
       var re = /you/gm;
    After the above statement executes, re.multiline is true.

    Now, what does setting this flag mean? First of all, its importance is _very_ limited. Despite its name, the 'm' flag has no bearing on the search for text matches extending across multiple lines of text in a string. All searches work across multiple-line strings. Period.

    The 'm' flag does apply, however, when the regular expression includes the ^ or $ symbols. For example, let's look at the ^ symbol, which indicates that the pattern must start at the beginning of a string. Here are some examples, using the multiline string:
       Are\n
       you\n
       happy?
    The regexp /you/ will find a match because the pattern "you" is someplace within the string.

    The regexp /^you/ will _not_ find a match because the string does not start with the pattern "you".

    The regexp /^you/m will find a match because the 'm' (multiline) flag says it's OK to treat each physical line of a multiline string as a start of a string.

    You have to be careful when you deploy the 'm' flag because not all browsers recognize it. It works in IE 5.5 or later for Windows and NN 6 or later. Not for IE/Mac or NN 4. Using the 'm' flag causes script errors in the older browsers.

  • Page 1198. The last line of the second code block for the increment (++) operator incorrectly shows the decrement (--) operator instead. The statement should be:
       b = a++;
    This kind of typo drives me nuts!

Notes

  • IE Bug with location.href Property. Reader Charles Roth reports an IE bug I had not seen before:
    Specifically, if I go to page A, and then click on an intra-page link to A#B, then press Back... the address bar shows "A", but location.href is still "A#B". Something to keep in mind if you have links to intra-page anchors and rely on reading the location.href property.

  • The Static Image Object. Chapter 9 has no explicit entry for the static Image object demonstrated on page 109 and elsewhere. This object lives in every window, and exists for the sole purpose of creating an unseen object capable of forcing the browser to preload an image into its image cache. You create an instance of the static object by invoking the new Image() constructor, with optional integer parameters for the width and height of the image. After that, this unseen image object has the same properties as an img element object. Assigning a URL string to the src property of this kind of image object triggers the invisible download of the image to the browser's cache.

  • Mozilla -moz-opacity Style Property. The Mozilla folks have dropped initial support for percentage values for this proprietary style property. Acceptable values must range between 0.0 and 1.0, inclusive (more in keeping with the CSS3 proposed opacity style property).

  • IE showModalDialog() Issues. Reader Steinar Overbeck Cook from Norway has been kind enough to share his ingenious solutions to some inherent problems in the IE showModalDialog() window with respect to form submission and cookies. These pseudo-windows don't obey all of the rules that regular windows do. Therefore, if you submit a form from a dialog window, the page returned from a server opens a new browser window -- unless you use Steinar's technique. The other problem is that cookies from the main window do not carry over to the dialog window, even when both windows originate from the same domain and server. Once again, Steinar has the solution. Read the details in his JavaScript modalWindow.js library. And many thanks to Steinar for his excellent detective work!

  • setAttribute() Gotcha in IE/Win. While the W3C DOM gives preference to using setAttribute() for scripted attribute value assignments (rather than assigning a value to the object's property), IE for Windows has a problem when doing so with event handler attributes. For example, if you try:
       document.getElementById("myElem").setAttribute("onclick", "doSomethingNew()");
    most browsers correctly resolve the assignment statement immediately so that the onclick property of that element object is a reference to the event handler function object. IE/Windows, however, does not resolve the statement, leaving the property value a simple string...which does not compute. If you want to assign or reassign an event handler for an element, use other syntaxes available for that purpose: cross-browser compatible direct property assignment (elemObj.onclick=doSomethingNew;), or event model-specific event assignment methods (W3C DOM's addEventListener() or IE's attachEvent()).

  • position:fixed() Gotcha in IE/Mac. The position:fixed CSS property doesn't get used much because IE for Windows (through version 6) still doesn't support this very useful behavior. While IE for Macintosh does support it, there are some undesirable side effects for DHTML scripters. Links (or client-side image maps) inside fixed-positioend elements do not receive onmouseover or onmouseout events. Nor does the cursor change to the hand or show the link's URL in the status bar. Clicking the link works, but if you are trying to execute script code with the mouse events, you're out of luck. No known workaround exists, except to eliminate that positioning style for IE/Win browser visitors.

  • DHTMLAPI.js Streamlining. Reader Nathan Niesen passes along an interesting variation on one aspect of the DHTMLAPI.js library (pp. 89ff). The basic idea is to remove the browser branching from the functions (especially those that get called frequently, such as getRawObject()). Instead, let the branching occur only once (while the library loads), and define a separate function for the current browser. For example:
       if (isW3C) {
          function getRawObject(obj) {
             return (typeof obj == "string") ? document.getElementById(obj) : obj;
          }
       } else if (isIE4) {
          function getRawObject(obj) {
             return (typeof obj == "string") ? document.all(obj) : obj;
          }
       } else if (isNN4) {
          function getRawObject(obj) {
             return (typeof obj == "string") ? seekLayer(document, obj) : obj;
          }
       } else {
          function getRawObject(obj) {
             return (typeof obj == "string") ? null : obj;
          }
       };
    Other advantages to this approach are increased readability and the ability to isolate branch-specific code for testing.

    I haven't done any benchmark testing to see if this speeds up performance on execution-intensive operations (such as dragging an element), but theoretically, it should be more streamlined because no branching occurs during cycle-intensive operations. Thanks Nathan!

  • Netscape 6+ Sidebars. You can learn about creating Sidebar tabs for Netscape 6+ at http://devedge.netscape.com/viewsource/2002/sidebar/. HTML content inside a sidebar can contain hyperlinks that load pages into the main browser viewing area by setting the element's target attribute to _content.

  • Image Type input Elements. Perhaps for historical reasons (in DOM Level 0, the image type input element was not addressable as an object), you cannot reference an image type input element through the Level 0 referencing scheme of document.formName.inputName. Nor do these controls show up in the collection returned by a form's elements property. The exception to this is IE/Mac, which does allow such references.