Chapter 2: Cross-Platform Compromises
In this chapter:
Declaring support for industry standards is a noble act. But
when each web browser maker is also out to put its stamp on
the details of still-evolving standards, it's easy to see
how a new browser release can embody ideas and extensions
to standards that are not available in other browsers. With
so many standards efforts related to Dynamic HTML in play
at the release of both Netscape Navigator 4 and Microsoft
Internet Explorer 4, implementation differences were bound
to occur. This chapter provides an overview of each browser's
approach to DHTML. It also explores some strategies that you
might use for DHTML applications that must run identically
on Navigator and Internet Explorer.
What Is a Platform?
The term
platform has multiple meanings in web application
circles, depending on how you slice the computing world. Typically,
a platform denotes any hardware and/or software system that
forms the basis for further product development. Operating
system developers regard each microprocessor family as a platform
(Pentium, PowerPC, or SPARC CPUs, for example); desktop computer
application developers treat the operating system as the platform
(Win16, Windows 95/NT, MacOS8, Unix, Linux, and the rest);
peripherals makers perceive a combination of hardware and
operating system as the platform (for example, a Wintel machine
or a Macintosh).
The de facto acceptance of the web protocols, such as HTTP,
means that a web application developer doesn't have to worry
about the underlying network transport protocols that are
being used. Theoretically, all client computers equipped
with browsers that support the web protocols-regardless
of the operating system or CPU-should be treated as a single
platform. The real world, however, doesn't work that way.
Today's crop of web browsers are far more than data readers.
Each one includes a highly customized content rendering
engine, a scripting language interpreter, a link to a custom
Java virtual machine, security access mechanisms, and connections
to related software modules. The instant you decide to author
content that will be displayed in a web browser, you must
concern yourself with the capabilities built into each browser.
Despite a certain level of interoperability due to industry-wide
standards, you must treat each major browser brand as a
distinct development platform. Writing content to the scripting
API or HTML tags known to be supported by one browser does
not guarantee support in the other browser.
If you are creating content, you must also be aware of
differences in the way each browser has been tailored to
each operating system. For example, even though the HTML
code for embedding a clickable button inside a form is the
same for both Navigator and Internet Explorer, the look
of that button is vastly different when rendered in Windows,
Macintosh, and Unix versions of either browser. That's because
the browser makers have appropriately observed the traditions
of the user interface look and feel for each operating system.
Thus, a form whose elements are neatly laid out to fit inside
a window or frame of a fixed size in Windows may be aligned
in a completely unacceptable way when displayed in the same
browser on a Macintosh or a Unix system.
Even though much of the discussion in this book uses "cross-platform"
to mean compatible with both Netscape and Microsoft browsers
("cross-browser" some might call it), you must
also be mindful of operating-system-specific details. Even
the precise positioning capabilities of "cross-platform"
cascading style sheets do not eliminate the operating-system-specific
vagaries of form elements and font rendering. If you are
developing DHTML applications, you can eliminate pre-version
4 browsers from your testing matrix, but there are still
a number of browser and operating system combinations that
you need to test.
Navigator 4 DHTML
As early as Navigator 2, JavaScript offered the possibility
of altering the content being delivered to a browser as a
page loaded. It was Navigator 3, however, that showed the
first glimpse of what Dynamic HTML could be. This browser
implemented the IMG HTML element as a document object whose
SRC attribute could be changed on the fly to load an entirely
different image file into the space reserved by the <IMG>
tag. In DHTML parlance, this is known as a replaced element
because it is rendered as an inline element (capable of flowing
in the middle of a text line), yet its content can be replaced
afterward. The most common application of this replacement
feature is the mouse rollover, in which an image is replaced
by a highlighted version of that image whenever the user positions
the cursor atop the image. If you surround the <IMG>
tag with a link (<A>) tag, you can use the link's mouse
event handlers to set the image object's source file when
the cursor rolls atop the image and when it rolls away from
the image:
<A HREF="someURL.php"
onMouseOver="document.images['logo'].src = 'images/logoHOT.jpg'"
onMouseOut="document.images['logo'].src = 'images/logoNORMAL.jpg'">
<IMG NAME="logo" SRC="images/logoNORMAL.jpg" HEIGHT=40 WIDTH=80>
</A>
At the time, this capability was a breakthrough that allowed
dynamic content without the delay of loading a Java applet
or rich media for a plug-in. Navigator 3 even allowed JavaScript
to pre-cache all images on a page during the initial page
download, so that the first image transition was instantaneous.
A glaring limitation of this scheme, however, hindered
some designs. The size of the image area was fixed by the
IMG element's HEIGHT and WIDTH attributes when the page
loaded. All other images assigned to that object had to
be the same size or risk being scaled to fit. While rarely
a problem for mouse rollovers, the lack of size flexibility
got in the way of more grandiose plans.
While the replaceable image object is still
a part of Navigator 4, if for no other reason than backward
compatibility, this version of the browser has added even
more dynamic capabilities.
Cascading Style Sheets Level 1
Navigator 4 includes support for the majority of the CSS1
recommendation (see Chapter 1, The State of the Art). The
unsupported features in Navigator 4 are detailed in Chapter
3, Adding Style Sheets to Documents. CSS1 style sheets are
not as dynamic in Navigator 4 as you might wish, however.
Styles and properties of content already loaded in the browser
cannot be changed. To do something like flash the color of
a block of text, you must create the content for each color
as a separate positioned element that can be hidden and shown
with the help of a script.
JavaScript Style Sheet Syntax
To further support the use of JavaScript in Navigator 4, Netscape
has devised an alternate syntax for setting style attributes
that uses JavaScript. The "dot" syntax for specifying
styles follows the syntax of the core JavaScript language,
rather than the CSS1 attribute:value syntax. The TYPE attribute
of the <STYLE> tag lets you define the style sheet syntax
you are using for a definition. For example, the following
samples set the left margin for all <H1> elements in
a document to 20 pixels, using CSS1 and JavaScript syntax,
respectively:
<STYLE TYPE="text/css">
H1 {marginLeft:20px}
</STYLE>
<STYLE TYPE="text/javascript">
tags.H1.marginLeft=20
</STYLE>
The JavaScript style sheet syntax is supported only in Navigator,
whereas the CSS1 syntax is supported in both Navigator and
Internet Explorer.
CSS-Positioning
Navigator supports the CSS-P recommendation as it was defined
in the most recent working draft prior to the release of Navigator
4 (see Chapter 1). You can use the cascading style sheet syntax
to define items on a page whose location and visibility can
be changed after a document has fully loaded. If an element
is positionable, its style sheet rule must include the position
attribute. In the following example, positioning attributes
are set for an element that identifies itself with an ID of
item1:
<STYLE type="text/css">
#item1 {position:absolute; top:50px; left:100px}
</STYLE>
In the body of the document, the style sheet rule is connected
to an element by assigning item1 to the ID attribute of an
element (a DIV element in this example):
<DIV ID="item1">
<IMG SRC="myFace.jpg" HEIGHT=60 WIDTH=40>
</DIV>
Alternatively, you can use the
STYLE attribute
(from CSS1-type style sheets) inside the affected element
to set position properties:
<DIV STYLE="position:absolute; top:50; left:100">
<IMG SRC="myFace.jpg" HEIGHT=60 WIDTH=40>
</DIV>
A positionable container is reflected as an object in the
Navigator document object model. Each of these objects has
a number of properties and methods that a script can use to
move, clip, hide, and show the content of that container.
Layers
A Netscape-specific alternative to CSS-Positioning utilizes
a document model object created with the <LAYER> tag.
You can think of each layer as a content holder that exists
in its own transparent plane above the base document in the
window. Many graphic programs, such as Photoshop, use the
same metaphor. The content, position, and visibility of each
layer are independent of the base document and any other layer(s)
defined within the window. Layers can also be created anew
by JavaScript (with the Layer() constructor) after a page
has been loaded, allowing for the dynamic addition of new
content to a page (content in its own layer, rather than inserted
into the existing content space).
Content for a layer is defined as HTML content, most often
loaded in from a separate HTML file. As a result, each layer
contains its own document object, distinct from the base
document object. Such a document may also include definitions
for additional layers, which can be nested as many levels
deep as needed for the application design.
As document model objects, layer objects have
properties and methods that are accessible to JavaScript.
As a convenience for cross-platform compatibility, Navigator
treats a positionable element defined via CSS-P syntax or
the <LAYER> tag as the same kind of object. The same
scriptable properties and methods are associated with both
kinds of positionable elements in Navigator.
Limited Dynamic Content
Navigator 4's document object model is only slightly enhanced
over the first model that appeared in Navigator 2. Once a
document has loaded into a window or frame, a script can do
very little to modify a portion of the page without reloading
the entire document. Swapping images in place, loading new
content into a layer, and setting the location of a positionable
element are about as far as you can go in making HTML content
dynamic in Navigator 4.
Event Capturing
When you script positionable elements, it is often convenient
to have user actions handled not by the specific objects being
clicked on, typed into, or dragged, but by scripts that encompass
a range of related object behaviors. Navigator 4 supports
objects that have this broader view-window, document, and
layer objects specifically-and can intercept events before
they reach their intended targets. A script then has the flexibility
to respond to the event and either let the event pass on to
the target or even redirect the event to another target.
Downloadable Fonts
A document to be displayed in Navigator 4 can include a CSS
style attribute or a <LINK> tag that instructs the browser
to download a Bitstream TrueDoc font definition file. Each
font definition file can contain more than one font definition,
so one reference to a font file can load all the necessary
fonts for a page. Here are the two techniques for downloading
a font:
<STYLE TYPE="text/css">
@fontdef url("http://www.mySite.com/fonts/someFonts.pfr")
</STYLE>
<LINK REL=fontdef SRC="http://www.mySite.com/fonts/someFonts.pfr">
Once a font has been downloaded into the browser, it is applied
to text by way of the <FONT FACE="faceName"></FONT>
tag set.
Internet Explorer 4 DHTML
While Internet Explorer 3 (for Windows) did not even allow
for swapping of images after a document loaded, IE 4 provides
substantial facilities for dynamically modifying the content
of a page after it has loaded. In addition, you can dynamically
create content during loading with the help of VBScript or
JScript, just as you could in IE 3. IE 4 exposes virtually
every element defined by HTML in a document to the scripting
language of your choice.
Cascading Style Sheets Level 1
Some CSS functionality was introduced in IE 3, but almost
every aspect of the W3C recommendation for CSS1 is implemented
in IE 4. Only a few CSS1 attributes, such as word-spacing
and white-space, are missing from the IE 4 implementation.
CSS-Positioning
In addition to supporting the specifications of the working
draft of CSS-Positioning that existed at the time of IE 4's
release in 1997, the browser also allows you to apply CSS-P
attributes to individual HTML elements-including those that
are not containers. Therefore, you can assign a specific position
and visibility to, say, an image, even when it is not surrounded
by a container tag such as <DIV> or <SPAN>:
<IMG SRC="myFace.jpg" HEIGHT=60 WIDTH=40
STYLE="position:absolute; left:200; top:100">
Of course, you can also assign positioning attributes to containers,
if you prefer.
Dynamic Content
IE 4's rendering engine is designed in such a way that it
can respond very quickly to changes in content. The browser's
document object model provides access to virtually every kind
of content on a page for modification after the document has
loaded. For example, a script can alter the text of a specific
<H1> header or the size of an image at any time. The
rendering engine instantaneously reflows the page to accommodate
the newly sized content. With each HTML element exposed to
scripting as an object, most properties can be changed on
the fly. The model even accommodates changing the HTML associated
with an element. For example, you can demote an <H1>
heading to an <H3> heading, with the same or different
text, by adjusting one property of the original object.
Event Bubbling
As part of IE 4's document object model definition, virtually
every object has event handlers that can be scripted to respond
to user and system actions. For example, it is possible to
associate different actions with user clicks over different
headings (even if they are not visibly displayed as links)
by assigning a different script statement to each heading's
onClick event handler. Moreover, unless otherwise instructed
by script, an event continues to "bubble up" through
the HTML element containment hierarchy of the document. Consider
the following simple HTML document:
<HTML>
<BODY>
<DIV>
<P>Some Text:</P>
<FORM>
<INPUT TYPE="button" VALUE="Click me" onClick="alert('Hi!')">
</FORM>
</DIV>
</BODY>
</HTML>
When the user clicks on the button, the click event is first
processed by the onClick event handler in the button's own
tag. Then the click event propagates through the FORM, DIV,
and BODY elements. If the tag for one of those elements were
to have an onClick event handler defined in it, the click
event would trigger that handler. Event bubbling can also
be programmatically canceled at any level along the way.
Transitions and Filters
Building atop the syntactical conventions of CSS1, IE 4 includes
a style attribute called filter. This attribute serves double
duty. One set of attribute parameters supplies extra display
characteristics for certain types of HTML content. For example,
you can set a filter to render content with a drop shadow
or with its content flipped horizontally. The other set of
attributes lets you define visual transition effects for when
an object is hidden or shown, very much like the transition
effects you set in presentation programs such as PowerPoint.
Downloadable Fonts
A document to be displayed in Internet Explorer 4 can embed
TrueType font families downloaded from the server. You download
the font via CSS style attributes:
<STYLE TYPE="text/css">
@font-face {
font-family:familyName;
font-style:normal;
font-weight:normal;
src:url("someFont.eot")}
</STYLE>
With the basic font family downloaded into the browser, the
family can be assigned to content via CSS styles or <FONT>
tags.
Note that the downloadable font format differs between
Internet Explorer and Navigator. Each browser requires that
the font definition files be generated with a different
tool.
Data Binding
IE 4 provides hooks for ActiveX controls and Java applets
that communicate with text files or databases on the server.
Elements from these server-based data sources can be associated
with the content of HTML elements, essentially allowing the
document to access server data without processing a CGI script.
While data binding is not covered in depth in this book, I
mention it here because it is one of Microsoft's dynamic content
features.
Cross-Platform Strategies
If your DHTML application must run on both Netscape and Microsoft
browsers, you have a choice of several deployment strategies
to pursue: page branching, internal branching, common denominator
design, and custom API development. In all likelihood, your
application will employ a combination of these techniques
to get the same (or nearly the same) results on both platforms.
No matter how you go about it, you must know the capabilities
of each browser to provide equivalent experiences for users
of both browsers. The rest of this book is designed to help
you understand the capabilities of each browser, so the material
in this section is mostly about the different strategies you
can use.
Page Branching
Web pages that use absolute-positioned elements degrade poorly
when displayed in older browsers. The positioned elements
do not appear where their attributes call for, and, even worse,
the elements render themselves from top to bottom in the browser
window, in the order in which they appear in the HTML file.
Also, any elements that are to be hidden when the page loads
appear in the older browsers in their source code order. To
prevent users of older browsers from seeing visual gibberish,
you should have a plan in place to direct users of non-DHTML-capable
browsers to pages containing less flashy content or instructions
on how to view your fancy pages. A server-side CGI program
can perform this redirection by checking the USER_AGENT environment
variable sent by the client at connect-time and redirecting
different HTML content to each browser brand or version.
Alternatively, you can do the same branching strictly via
client-side scripting. Depending on the amount of granularity
you wish to establish for different browser brands and versions
at your site, you have many branching techniques to choose
from. All these techniques are based on a predominantly
blank page that has some scripted intelligence behind it
to automatically handle JavaScript-enabled browsers. Any
script-enabled browser can execute a script that looks into
the visitor's browser version and loads the appropriate
starter page for that user. Example 2-1
shows one example of how such a page accommodates both scripted
and unscripted browsers.
Example 2-1: Branching Index Page
<HTML>
<HEAD>
<TITLE>MegaCorp On The Web</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
if (parseInt(navigator.appVersion) >= 4) {
if (navigator.appName == "Netscape") {
window.location.href = "startNavDHTML.php"
} else if (navigator.appName.indexOf("Internet Explorer") != -1) {
window.location.href = "startIEDHTML.php"
} else {
window.location.href = "startPlainScripted.php"
}
} else {
window.location.href = "startPlainScripted.php"
}
//-->
</SCRIPT>
<META HTTP-EQUIV="REFRESH"
CONTENT="1;URL=http://www.megacorp.com/startUnscripted.php">
</HEAD>
<BODY>
<CENTER>
<A HREF="startUnscripted.php">
<IMG SRC="images/megaCorpLogo.gif" HEIGHT=60 WIDTH=120 BORDER=0
ALT="MegaCorp Home Page"></A>
</CENTER>
</BODY>
</HTML>
The script portion of
Example 2-1 provides
three possible branches, depending on the browser level. If
the browser version is 4 or later, this index page automatically
loads a Navigator-specific starter page for Netscape Navigator
users, an IE-specific starter page for IE users, or a starter
page that accommodates the outside chance of there being a
Version 4 browser of yet another brand. That same plain scripted
starter page is the one that all other JavaScript-enabled
browsers load.
For browsers that either don't have JavaScript built in
or have JavaScript turned off, a <META> tag refreshes
this page after one second by loading a starter page for
unscripted browsers. For "bare bones" browsers
that may not recognize scripting or <META> tags (including
Lynx and browsers built into a lot of handheld devices),
a simple image link leads to the unscripted starter page.
Users of these browsers will have to "click" on
this link to enter the content portion of the web site.
Example 2-1 is an extreme example. It
assumes that the application has as many as four different
paths for four different classes of visitor. This may seem
like a good idea at first, but it seriously complicates
the maintenance chores for the application in the future.
At best, it provides a way to filter access between DHTML-capable
browsers and all the rest.
Internal Branching
Instead of creating separate documents for Navigator and IE
4 users, you can use JavaScript to write browser-specific
content for a page within a single document. For example,
you may find that some style sheet specifications are not
rendered the same in both browsers. To get the same look for
an element, you can create a browser-specific branch to use
the JavaScript document.write() method to generate content
suited to each browser.
Example 2-2 show
a simplified page that writes HTML for a positionable element
two different ways. For Internet Explorer, the HTML is a DIV
container; for Navigator, it is a <LAYER> tag that loads
an external file (whose content is not shown in the example).
Example 2-2: Internal Branching for Browsers
<HTML>
<HEAD>
<TITLE>MegaCorp On The Web</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
var isNav4, isIE4
if (parseInt(navigator.appVersion) >= 4) {
isNav4 = (navigator.appName == "Netscape")
isIE4 = (navigator.appName.indexOf("Microsoft") != -1)
}
//-->
</SCRIPT>
</HEAD>
<BODY>
Some regular text
<SCRIPT LANGUAGE="JavaScript">
<!--
var output = ""
if (isIE4) {
output += "<DIV ID='help' "
output += "STYLE='position:absolute; top:75; width:350; border:none; "
output += "background-color:#98FB98;'>"
output += "<P STYLE='margin-top:5; align:center'><B>Instructions</B></P>"
output += "<HR><OL STYLE='margin-right:20'>"
output += "<LI>Step 1."
output += "<LI>Step 2."
output += "<LI>Step 3."
output += "</OL><DIV align='center'><BUTTON "
output += "onClick='document.all.help.style.visibility=\"hidden\" '>"
output += "Click Here</BUTTON></DIV></DIV>"
} else if (isNav4) {
output += "<LAYER ID='help' TOP=75 WIDTH=350 SRC='help.php'></LAYER>"
}
document.write(output)
//-->
</SCRIPT>
</BODY>
</HTML>
The key to efficient branching in such a page is establishing
a Boolean global variable for each browser at the top of the
document (isNav4 and isIE4 in
Example 2-2).
This allows scripts elsewhere in the document to make decisions
based on the browser that is running the script and writing
the HTML that applies to that browser. Notice in
Example
2-2 that the if construction writes HTML content only
if one of the two global variables is true. Conceivably, a
user who does not have a DHTML-capable browser could gain
access to the URL of this page. In this example, the only
content such a user would see is the short line of text after
the <BODY> tag.
Designing for the Common Denominator
From a maintenance point of view, the ideal DHTML page is
one that uses a common denominator of syntax that both browsers
interpret and render identically. You can achieve some success
with this approach, but you must be very careful in selecting
standards-based syntax (e.g., CSS1 and CSS-P) that is implemented
identically in both browsers. Because some of these standards
were little more than working drafts as the browsers were
released to the world, the implementations are not consistent
across the board.
DHTML feature sets that you can use as starting points
for a common denominator approach are the standards for
Cascading Style Sheets Level 1 and CSS-Positioning. When
you peruse the documentation from the browser vendors in
this arena, it is nigh impossible to distinguish support
for the recommended standard from a company's proprietary
extension that adheres to the spirit, but not the letter,
of the standard. Just because a feature is designated as
being "compatible with CSS" does not mean that
it is actually in the published recommendation. Refer to
the reference chapters in Part II of this book for accurate
information on the implementations in the browsers as it
relates to the standards.
You are likely to encounter situations in which the same
style sheet syntax is interpreted or rendered slightly differently
in each browser. This is one reason why it is vital to test
even recommended standards on both browser platforms. When
an incompatibility occurs, there is probably a platform-specific
solution that makes the result look and behave the same
in both browsers. To achieve this parity, you'll need to
use internal branching for part of the page's content. This
is still a more maintainable solution than creating an entirely
separate page for each browser.
Some features that are available in one browser cannot
be translated into the other browser. Internet Explorer
4 includes a few DHTML capabilities that have no parallel
features in Navigator 4. Therefore, don't expect to find
common denominators for dynamic content (beyond swapping
images of the same size), transitions, or filters. DHTML
facilities in Navigator 4 can be re-created in IE 4 either
directly or via internal branching. For example, the IE
4 <IFRAME> element closely resembles the Navigator
4 <ILAYER> element.
If this short lesson in finding a common denominator of
functionality reveals anything about the Version 4 browsers,
it is that if you start your design with Navigator 4 in
mind, you can probably develop an IE 4 version using some
or all of the techniques described in this chapter. But
if you start with IE 4 and get carried away with its DHTML
features, you may be disappointed when you run your application
in Navigator 4.
Custom APIs
Despite the common denominator of CSS1 and CSS-P recommendations
for the HTML elements in documents, scripted access to these
objects and their properties can vary substantially from one
browser to the other. Even when the two browsers have similar
objects with similar properties, the syntax for the property
names may be different enough that you need to use internal
branching for your application to work seamlessly across platforms.
Once you go to the trouble of writing scripts that perform
internal branching, you might prefer to avoid doing it again
for the next document. Both browsers allow JavaScript to
load libraries of script functions (files named with the
.js extension) that you can link into any HTML document
you like. You can therefore create your own meta language
for scripted DHTML operations by writing a set of functions
whose terminology you design. Place the functions in a library
file and rely on them as if they were part of your scripting
vocabulary. The language and function set you create is
called an application programming interface-an API. Example
2-3 shows a small portion of a sample DHTML API library.
Example 2-3: Portion of a DHTML Library
// Global variables
var isNav4, isIE4
var range = ""
var styleObj = ""
if (parseInt(navigator.appVersion) >= 4) {
if (navigator.appName.indexOf("Microsoft") != -1) {
isNav4 = true
} else {
isIE4 = true
range = "all."
styleObj = ".style"
}
}
// Convert object name string or object reference
// into a valid object reference
function getObject(obj) {
var theObj
if (typeof obj == "string") {
theObj = eval("document." + range + obj + styleObj)
} else {
theObj = obj
}
return theObj
}
// Positioning an object at a specific pixel coordinate
function shiftTo(obj, x, y) {
var theObj = getObject(obj)
if (isNav4) {
theObj.moveTo(x,y)
} else {
theObj.pixelLeft = x
theObj.pixelTop = y
}
}
One of the incompatibilities between positionable elements
in Navigator 4 and IE 4 is the format of references to the
element's properties and methods. For an unnested Navigator
layer object (remember that all positionable items in Navigator
are treated as layer objects), a reference must begin with
the document object reference (e.g., document.layerName).
In contrast, properties that govern IE 4 positionable elements
are properties of a style property associated with the object.
Moreover, every named object, no matter how deeply nested
within other containers, can be referenced from the document
object if the all keyword is included in the reference (e.g.,
document.all.objectName.style).
The getObject() function of Example
2-3 is an all-purpose function that returns a reference
to an object that is passed originally as either a string
that contains the object name or a ready-to-go object reference.
When the incoming object name is passed as a string, the
eval() function assembles a valid reference based on the
browser running the script. If the browser is Navigator
4, the range and styleObj variables are empty strings, and
the resulting reference being evaluated is "document.objectName";
in IE 4, the keywords all and style are assembled as part
of the reference. For both browsers, when the incoming parameter
is already an object reference, it is passed straight through:
the assumption is that the object reference is valid for
the current browser (probably based on internal branching
in the main document that calls this function).
The more interesting function in Example
2-3 is shiftTo(), which changes the position of an object,
so that it is located at the specific coordinates that are
passed as parameters. Each browser has its own way to set
the position of an object in a script. Navigator 4 features
a one-step moveTo() method of a layer object; IE 4 requires
setting the pixelLeft and pixelTop properties of the object's
style property. Those differences, however, are handled
by the function. Any time you need scripted control of the
movement of an item in a document, you can call the shiftTo()
function to do the job in whatever browser is currently
running.
Building an API along these lines lets you raise the common
denominator of DHTML functionality for your applications.
You free yourself from limits that would be imposed by adhering
to 100% syntactical compatibility. In Chapter 4, Adding
Dynamic Positioning to Documents, I present a more complete
custom API that smooths over potentially crushing CSS-Positioning
incompatibilities.
Cross-Platform Expectations
Before undertaking cross-platform DHTML development, be sure
you understand that the features you can exploit in both browsers-regardless
of the techniques you use-are limited to comparable feature
sets within the realms of style sheets, positionable elements,
event models, object models, and downloadable fonts. Dynamic
content on a small scale is also a cross-platform possibility,
but the instantaneous reflowing of modified content, display
filters, and transitions that are available in Internet Explorer
4 have no parallels in Navigator 4.