Tải bản đầy đủ (.pdf) (10 trang)

JavaScript Bible, Gold Edition part 26 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (192.67 KB, 10 trang )

98
Part III ✦ Document Objects Reference
Of the three models, NN4’s DOM is the trickiest one to deal with at the HTML
level. While it may be possible that your content design will look the same using
positioned DIV and SPAN elements in all DHTML-capable browsers, often the
appearance in NN4 is unacceptable. At that point, you will probably have to use
scripts in your Body to dynamically generate HTML, specifying the
<LAYER> tag
for NN4 and positioned
<DIV> elements for the rest.
Although IE4 and IE5.x can use the same basic Microsoft object model, not all
DHTML code renders the same on both generations of browsers. Microsoft made
some changes here and there to the way some style attributes are rendered so
that IE5.x comes into better compliance with the CSS recommendation.
Using script libraries
As long as you plan to use scripts to dynamically generate HTML for the page,
you might consider creating separate, external
.js libraries for each of the object
models you want to support for the page. Scripts in each library contain code for
both the HTML accumulation (for use with
document.write() in the main page)
and for processing user interaction. Assuming that only DHTML-capable browsers
reach the page, branching is required only at the beginning of the document where
an object model-specific library is loaded:
var isIE4 = ((navigator.appName.indexOf(“Microsoft”) == 0 &&
parseInt(navigator.appVersion) == 4))
var isW3C = (document.documentElement) ? true : false
if (isW3C) {
// give priority to W3C model for IE5.x
document.write(“<SCRIPT LANGUAGE=’JavaScript’ SRC=’page3_W3C.js’><” +
“\/SCRIPT>”)


} else if (isIE4) {
document.write(“<SCRIPT LANGUAGE=’JavaScript’ SRC=’page3_IE4.js’><” +
“\/SCRIPT>”)
} else {
document.write(“<SCRIPT LANGUAGE=’JavaScript’ SRC=’page3_generic.js’><” +
“\/SCRIPT>”)
}
Each of the statements that writes the <SCRIPT> tag includes a workaround that
is required on some browsers (NN4 especially) to facilitate using
document.write() to write script tags to the page.
Once these libraries are specified for the page, script statements anywhere later
in the page can invoke functions defined in each library to generate a particular
element or set of elements in the object model HTML optimized for the current
browser. Of course, it’s not necessary to have one library devoted to each object
model. You might find it more convenient for authoring and maintenance to keep
all the code in one library that has numerous internal branchings for browser ver-
sions. Branches in a library can use the version sniffing global variables defined in
the main HTML page’s scripts. Better still, a library can be entirely self-contained
by using object detection. You can see an example of such a DHTML library in
Chapter 48.
Note
99
Chapter 14 ✦ Document Object Model Essentials
Handling events
Thanks to the W3C DOM’s event model implementing a similar event bubbling
scheme as IE4+, you can apply that event propagation model to IE4+ and W3C DOM
browsers. There are differences in the details, however. IE’s approach does not pass
the event object as a parameter to a function invoked by an event handler. Instead,
the IE
event object is a property of the window object. Therefore, your functions

have to look for the passed parameter and substitute the
window.event object in
its place for IE:
function calculate(evt) {
evt = (evt) ? evt : window.event
// more statements to handle the event //
}
Additional branching is necessary to inspect many details of the event. For
example, IE calls the object receiving the event the
srcElement, while the W3C
DOM calls it the
target. Canceling the default behavior of the event (for example,
preventing a form’s submission if it fails client-side validation) is also different for
the models (although the “old-fashioned” way of letting HTML-type event handlers
evaluate to
return false still works). You can find more event object details in
Chapter 29.
Simulating IE4+ Syntax in NN6
With so much IE4+ DHTML-related JavaScript code already in use, scripters are
certainly eager to leverage as much of their old code as possible in W3C DOM
browsers such as NN6. While NN6 helps a bit by implementing the IE
innerHTML
property for HTML elements, this section shows you how a simple .js library can
provide NN6 with a few more common convenience properties of the IE4+ object
model. By linking this library into your pages, you can give NN6 the valuable HTML
element properties shown in Table 14-8.
Table 14-8 IE4+ HTML Element Property Simulation for NN6
Property Read Write Replaces in W3C DOM
all yes no getElementsByTagName(“*”)
innerText yes yes nodeValue property for text nodes; creating a

text fragment node and inserting it into existing
node structure
outerHTML no yes (No equivalent)
Scripts that make these simulations possible use the prototype inheritance
behavior of static objects described earlier in this chapter. Because they require
100
Part III ✦ Document Objects Reference
NN6-specific features in that browser’s implementation of JavaScript 1.5, link the
.js library with the following tag:
<SCRIPT LANGUAGE=”JavaScript1.5” TYPE=”text/javascript”
SRC=”IE4Simulator.js”></SCRIPT>
All scripts that follow belong in the .js library. They’re divided into two groups
to allow for detailed discussion.
The all property simulator
Nearly every HTML element can be a container of other elements (with the
exception of a handful of leaf nodes, such as
<BR>). The all property in IE returns a
collection of references to all element objects nested inside the current object, no
matter how deeply nested the containment hierarchy is. That’s why the
docu-
ment.all
reference is such a convenient way to access any element in the entire
document that has an
ID attribute.
As illustrated earlier in the sidebar figure, the
Node static object is the object
from which all elements are derived. That object’s prototype is enhanced here
because you have to make sure that all nodes, especially the document node, can
acquire the
all property. Listing 14-4a shows the segment of the library that

defines the
all property for the Node object prototype.
Listing 14-4a: Simulator for the all Property
if (!document.all) {
Node.prototype.__defineGetter__(“all”, function() {
if (document.getElementsByTagName(“*”).length) {
switch (this.nodeType) {
case 9:
return document.getElementsByTagName(“*”)
break
case 1:
return this.getElementsByTagName(“*”)
break
}
}
return “”
})
Node.prototype.__defineSetter__(“all”, function() {})
}
This portion of the library exhibits a rare instance in which using object detec-
tion for
document.all does the right thing now and in the future. The prototype
should not execute if the browser loading the page already has a
document.all
property.
The anonymous function first establishes a branch in the code only for the
object model if it supports the wildcard parameter for the
document.getElementsByTagName() method. The function then performs slightly
different extractions depending on whether the node is the document (type 9) or an
element (type 1). If the

all property should be queried for any other kind of node,
the returned value is an empty string. Each time the
all property is accessed, the
anonymous function executes to pick up all elements nested inside the current
101
Chapter 14 ✦ Document Object Model Essentials
node. Therefore, the collection returned by the all property is always up to date,
even if the node structure of the current object changes after the document loads.
While this simulator code provides NN6 scripts with IE4-like syntax for referenc-
ing elements, the collection returned by the native
document.all in IE and calcu-
lated
document.all in NN6 may not always have an identical length — the
collections are derived slightly differently. The important thing to know, however, is
that by employing this prototype modifier in NN6, you have the ability to reference
elements by their IDs in the form
document.all.elementID.
The content properties simulators
The remaining code of this library lets NN6 use the same innerText and
outerHTML properties as IE4 for modifying all element objects. Listing 14-4b con-
tains the NN6 JavaScript code that prepares the browser to set an element object’s
outerHTML property, as well as get and set the innerText properties. The code
again uses anonymous functions assigned to
getter and setter behaviors of proto-
type properties. Because the properties here apply only to HTML elements, the static
object whose prototype is being modified is
HTMLElement. All specific HTML element
objects inherit properties and methods from the
HTMLElement object. All four proto-
type adjustment blocks are nested inside a condition that makes sure the static

HTMLElement object is exposed in the browser’s object model (which it is in NN6+).
All functions in Listing 14-4b use the W3C DOM
Range object (Chapter 19). Two
of them use a Netscape-proprietary method of the
Range object as a shortcut to
converting a string into a node hierarchy.
Listing 14-4b: Simulator for the innerText and outerHTML
Properties
if (HTMLElement) {
HTMLElement.prototype.__defineSetter__(“innerText”, function (txt) {
var rng = document.createRange()
rng.selectNodeContents(this)
rng.deleteContents()
var newText = document.createTextNode(txt)
this.appendChild(newText)
return txt
})
HTMLElement.prototype.__defineGetter__(“innerText”, function () {
var rng = document.createRange()
rng.selectNode(this)
return rng.toString()
})
HTMLElement.prototype.__defineSetter__(“outerHTML”, function (html) {
var rng = document.createRange()
rng.selectNode(this)
var newHTML = rng.createContextualFragment(html)
this.parentNode.replaceChild(newHTML,this)
return html
})
HTMLElement.prototype.__defineGetter__(“outerHTML”, function() {return ‘’})

}
102
Part III ✦ Document Objects Reference
The getter function for the innerText property creates a range whose bound-
aries encompass the current object. Because a range includes only the text part of a
document, the adjustment of the range boundaries to the current node encom-
passes all text, including text nodes of nested elements. Returning the string ver-
sion of the range provides a copy of all text inside the current element.
For the setter action, the anonymous function defines one parameter variable,
which is the text to replace the text inside an element. With the help, again, of the
Range object, the range is cinched up to encompass the contents of the current
node. Those contents are deleted, and new text node is created out of the value
assigned to the property (in other words, passed as a parameter to the anonymous
function). With the current object no longer containing any nodes after the dele-
tion, the
appendChild() method inserts the new text node as a child to the current
object.
Setting the
outerHTML property starts out the same as setting the innerText,
but the new content — which arrives as a string assigned to the parameter
variable — is converted into a fully formed set of nested nodes via the
createContextualFragment() method. This method is invoked on any range
object, but it does not affect the range to which it is attached. The value returned
from the method is what’s important, containing a node whose content is already
set up as genuine DOM nodes. That’s why the returned value can be passed to the
replaceChild() method to replace the new content as HTML rather than plain
text. But because the
outerHTML property applies to the entire current element, it
must use the roundabout way of replacing itself as a child of its parent. This pre-
vents the accidental modification of any siblings in the process.

Where to Go from Here
These past two chapters provided an overview of the core language and object
model issues that anyone designing pages that use JavaScript must confront. The
goal here is to stimulate your own thinking about how to embrace or discard levels
of compatibility with your pages as you balance your desire to generate “cool”
pages and serve your audience. From here on, the difficult choices are up to you.
To help you choose the objects, properties, methods, and event handlers that
best suit your requirements, the rest of the chapters in Part III and all of Part IV pro-
vide in-depth references to the document object model and core JavaScript lan-
guage features. Observe the compatibility ratings for each language term very
carefully to help you determine which features best suit your audience’s browsers.
Most example listings are complete HTML pages that you can load in various
browsers to see how they work. Many others invite you to explore how things work
via The Evaluator (Chapter 13). Play around with the files, making modifications to
build your own applications or expanding your working knowledge of JavaScript in
the browser environment.
103
Chapter 14 ✦ Document Object Model Essentials
The language and object models have grown in the handful of years they have
been in existence. The amount of language vocabulary has increased astronomi-
cally. It takes time to drink it all in and feel comfortable that you are aware of the
powers available to you. Don’t worry about memorizing the vocabulary. It’s more
important to acquaint yourself with the features, and then come back later when
you need the implementation details.
Be patient. Be persistent. The reward will come.
✦✦✦
Generic HTML
Element Objects
T

he object model specifications implemented in Internet
Explorer 4+ and Netscape Navigator 6 both feature a
large set of scriptable objects that represent what we often
call “generic” HTML elements. Generic elements can be
divided into two groups. One group, such as the B and STRIKE
elements, define font styles to be applied to enclosed
sequences of text. The need for these elements (and the
objects that represent them) is receding as more browsers
accommodate style sheets. The second group of elements
assigns context to content within their start and end tags.
Examples of contextual elements include H1, BLOCKQUOTE,
and the ubiquitous P element. While browsers sometimes
have consistent visual ways of rendering contextual elements
by default (for example, the large, bold font of an
<H1> tag),
the specific rendering is not the intended purpose of the tags.
No formal standard dictates that text within an EM element
must be italicized: the style simply has become the custom
since the very early days of browsers.
All of these generic elements share a large number of
scriptable properties, methods, and event handlers. The shar-
ing extends not only among generic elements, but also among
virtually every renderable element — even if it has additional,
element-specific properties, methods, and/or event handlers
that I cover in depth in other chapters of this reference.
Rather than repeat the details of these shared properties,
methods, and event handlers for each object throughout this
reference, I describe them in detail only in this chapter
(unless there is a special behavior, bug, or trick associated
with the item in some object described elsewhere). In suc-

ceeding reference chapters, each object description includes
a list of the object’s properties, methods, and event handlers,
but I do not list shared items over and over (making it hard to
find items that are unique to a particular element). Instead,
you see a pointer back to this chapter for the items in com-
mon with generic HTML element objects. A dark tab at the
bottom of this chapter’s pages should make it easy to find this
chapter in a hurry.
15
15
CHAPTER
✦✦✦✦
In This Chapter
Working with HTML
element objects
Common properties
and methods
Event handlers of all
element objects
✦✦✦✦
106
Part III ✦ Document Objects Reference
Generic Objects
Table 15-1 lists all of the objects that I treat in this reference as “generic” objects.
All of these objects share the properties, methods, and event handlers described in
succeeding sections and have no special items that require additional coverage
elsewhere in this book.
Table 15-1 Generic HTML Element Objects
Formatting Objects Contextual Objects
B ACRONYM

BIG ADDRESS
CENTER CITE
I CODE
NOBR DFN
RT DEL
RUBY DIV
SEM
SMALL INS
STRIKE KBD
SUB LISTING
SUP P
TT PLAINTEXT
U PRE
WBR SAMP
SPAN
STRONG
VAR
XMP
Properties Methods Event Handlers
accessKey addBehavior() onActivate
all addEventListener() onBeforeCopy
attributes appendChild() onBeforeCut
elementObject
107
Chapter 15 ✦ Generic HTML Element Objects
Properties Methods Event Handlers
behaviorUrns applyElement() onBeforeDeactivate
canHaveChildren attachEvent() onBeforeEditFocus
canHaveHTML blur() onBeforePaste
childNodes clearAttributes() onBlur

children click() onClick
className cloneNode() onContextMenu
clientHeight componentFromPoint() onControlSelect
clientLeft contains() onCopy
clientTop detachEvent() onCut
clientWidth dispatchEvent() onDblClick
contentEditable fireEvent() onDeactivate
currentStyle focus() onDrag
dataFld getAdjacentText() onDragEnd
dataFormatAs getAttribute() onDragEnter
dataSrc getAttributeNode() onDragLeave
dir getBoundingClientRect() onDragOver
disabled getClientRects() onDragStart
document getElementsByTagName() onDrop
filters getExpression() onFilterChange
firstChild hasChildNodes() onFocus
height insertAdjacentElement() onHelp
hideFocus insertAdjacentHTML() onKeyDown
id insertAdjacentText() onKeyPress
innerHTML insertBefore() onKeyUp
innerText item() onLoseCapture
isContentEditable mergeAttributes() onMouseDown
isDisabled normalize() onMouseEnter
isMultiLine releaseCapture() onMouseLeave
isTextEdit removeAttribute() onMouseMove
lang removeAttributeNode() onMouseOut
Continued
elementObject

×