Javascript [Electronic resources] : The Definitive Guide (4th Edition) نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Javascript [Electronic resources] : The Definitive Guide (4th Edition) - نسخه متنی

David Flanagan

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


20.1 Platform and Browser Compatibility


When developing production-quality
JavaScript code, testing and knowledge of platform-specific,
vendor-specific, and version-specific incompatibilities are your
chief allies. If you know, for example, that Netscape 2 on Macintosh
platforms always gets the time wrong by about an hour, you can take
steps to deal with this problem. If you know that Netscape 2 and 3 on
Windows platforms do not automatically clear your setting of the
status line when the mouse moves off a hypertext link, you can
provide an appropriate event handler to explicitly clear the status
line. If you know that Internet Explorer 4 and Netscape 4 support
vastly different Dynamic HTML models, you can write pages that use
the appropriate mechanism depending on the browser in use.

Knowledge of existing incompatibilities is crucial to writing
compatible code. Unfortunately, producing a definitive listing of all
known vendor, version, and platform incompatibilities would be an
enormous task. It is beyond the scope and mission of this book, and
it has apparently never even been seriously attempted. You may find
some assistance on the Internet, but you will have to rely primarily
on your own experience and testing. Once you have identified an area
of incompatibility, however, there are a number of basic approaches
you can take to coping with it, as described in the following
sections.


20.1.1 The Least-Common-Denominator Approach



One

technique
for dealing with incompatibilities is to avoid them like the plague.
For example, the Date object is notoriously buggy in Netscape 2. If
you want Netscape 2 users to be able to use your programs, you can
simply avoid relying on the Date object at all.[1]

[1] I
don't actually recommend doing this. At the time of this
writing, Netscape 2 is so far out of date that it is safe to ignore
it.

As another example, Netscape 3 and IE
3 both support the opener property of the Window
object, but Netscape 2 does not. The least-common-denominator
approach says that you should not use this property if compatibility
with Netscape 2 is a goal. Instead, you can create an equivalent
property of your own whenever you open a new window:

newwin = window.open(", "new", "width=500, height=300");
newwin.creator = self;

If you
consistently set a creator property for each new
window you create, you can rely on that property instead of the
nonportable opener property. (Another alternative,
as we'll see later, is to give up on compatibility with
Netscape 2 and require a browser that supports JavaScript 1.1 or
later, as all such browsers support the opener
property.)

With this technique, you use only features that are known to work on
all your target platforms. It doesn't allow you to write
cutting-edge programs or push the envelope, but it results in
portable, safe programs that can serve many important functions.


20.1.2 Defensive Coding


With the


defensive coding approach to
compatibility, you write code that contains platform-independent
workarounds for platform-specific incompatibilities. For example, if
you set the status property of a Window object
from the onmouseover event handler to display a
custom message in the status line, the status line is cleared when
you move the mouse off the hyperlink, except in Windows versions of
Netscape 2 and 3. To correct for this problem, you could get in the
habit of including an onmouseout event handler to
clear the status line. This precaution fixes the bug in current (and
future) platforms that have it and doesn't do any harm on
platforms that don't have the bug.


20.1.3 Feature Testing



Feature testing is a powerful
technique for


coping with incompatibilities. If you
want to use a feature that may not be supported by all browsers,
include code in your script that tests to see whether that feature is
supported. If the desired feature is not supported on the current
platform, either do not use it on that platform or provide
alternative code that works on all platforms.

Consider again the opener property. In the
least-common-denominator approach, we simply avoided the use of this
property and used an alternative on all platforms. With the
feature-testing approach, we provide the alternative only when the
current platform does not support opener:

newwin = window.open
(", "new", "width=500, height=300");
if (!newwin.opener) newwin.opener = self;

Note how we tested for the existence of the opener
property. The same technique works to test for the existence of
methods. For example, the split( ) method of the
String object exists only for JavaScript 1.1 implementations. We can
write our own version of this function that works in all versions of
JavaScript, but for efficiency we'd like to use the fast,
built-in method on those platforms that do support it. Thus, our
feature-testing code to split( ) a string might
end up looking like this:

if (s.split)  // Check if the method exists, without invoking it
a = s.split(":"); // If it does exist, it is safe to invoke it
else // Otherwise:
a = mysplit(s, ":"); // use our alternative implementation

Feature testing is commonly used for performing
DHTML effects
that are supported only on some browsers or are implemented
differently in different browsers. For example, if you are designing
a site that includes image rollover effects, you can use feature
testing with code like this:

if (document.images) 
{ // If the browser defines an images[] array,
// we include image rollover code here
}
// Otherwise, we simply omit the image rollover effect

As another example, suppose we want to work with a dynamically
positioned document element. Different browsers have different APIs
for doing this, so we first use feature testing to see which API is
supported by the current browser with code like this:

if (document.getElementById) 
{ // If the W3C DOM API is supported,
// do our DHTML using the W3C DOM API
}
else if (document.all)
{ // If the IE 4 API is supported,
// do our DHTML using the IE 4 API
}
else if (document.layers)
{ // If the Netscape 4 API is supported,
// do the DHTML effect (as best we can) using the Netscape 4 API
}
else { // Otherwise, DHTML is not supported,
// so provide a static alternative to DHTML, if we can
}

The nice thing about the feature-testing technique is that it results
in code that is not tied to a specific list of browser vendors or
browser version numbers. It works with the set of browsers that exist
today and should continue to work with future browsers, whatever
feature sets they implement.


20.1.4 Platform-Specific Workarounds



Feature testing is well suited to
checking for support of large functional areas. You can use it to
determine whether a browser supports image rollovers or the W3C DOM
API, for example. On the other hand, sometimes you may need to work
around individual bugs or quirks in a particular browser, and there
may be no easy way to test for the existence of the bug. In this
case, you will need to create a platform-specific workaround that is
tied to a particular browser vendor, version, or operating system (or
some combination of the three).

Recall from Chapter 13 that the
navigator property
of the Window object provides information about the vendor and
version of the browser and the operating system on which it is
running. You can use this information to insert platform-specific
code into your program.

An example of a platform-specific workaround involves
the bgColor
property of the Document object. On Windows and Macintosh platforms,
you can set this property at runtime to change the background color
of a
document. Unfortunately, when you do this on
Unix versions of Netscape 2 and 3, the color changes but the document
contents temporarily disappear. If you wanted to create a special
effect using a changing background color, you could use the Netscape
object to test for Unix platforms and simply skip the special effect
for those platforms. The code could look like this:

// Check whether we're running Netscape 2 or 3 on a Unix platform
var nobg = (parseInt(navigator.appVersion) < 4)
&& // Version
(navigator.appName.indexOf
("Netscape") != -1) && // Vendor
(navigator.appVersion.indexOf("X11") != -1); // OS
// If we're not, then go ahead and animate the page background color
if (!nobg) animate_bg_color( );

When writing platform-specific workarounds, it is common to use
"

client-sniffer" code to
determine what the current platform is, based (typically) on the
properties of the navigator object. You run your
client-sniffer code once, and it sets variables that describe the
current platform. Then you don't have to reparse the properties
of navigator for each platform-specific bit of
code you write; you can simply use the variables set by the sniffer
code. A simple sniffer that may be sufficient for many purposes might
look like this:

var browserVersion = parseInt(navigator.appVersion);
var isNetscape = navigator.appName.indexOf("Netscape") != -1;
var isIE = navigator.appName.indexOf("Microsoft") != -1;
var agent = navigator.userAgent.toLowerCase( );
var isWindows = agent.indexOf("win") != -1;
var isMac = agent.indexOf("mac") != -1;
var isUnix = agent.indexOf("X11") != -1;

With variables like these defined, you might write code like the
following:

if (isNetscape && browserVersion < 4 && isUnix) {
// Work around a bug in Netscape 3 on Unix platforms here
}

A variety of prewritten client sniffers are available on the
Internet. You can find a thorough one (along with a helpful
discussion of its use) at http://www.mozilla.org/docs/web-developer/sniffer/browser_typel.


20.1.5 Compatibility Through Server-Side Scripts


Another
platform-specific


approach to compatibility is possible if
your web application includes the use of server-side scripts, such as
CGI scripts or server-side JavaScript. A program

on the server
side can inspect the User-Agent field of the HTTP
request header, which allows it to determine exactly what browser the
user is running. With this information, the program can generate
customized JavaScript code that is known to work correctly on that
browser. Or, if the server-side script detects that the user's
browser does not support JavaScript, it can generate web pages that
do not require JavaScript at all. An important drawback to this
approach is that a server-side script cannot detect when a user has
disabled JavaScript support in her browser.

Note that the topics of CGI programming and server-side scripting in
general are beyond the scope of this book.


20.1.6 Ignore the Problem


An important


question to ask when
considering any incompatibility is, how important is it? If the
incompatibility is minor or cosmetic, affects a browser or platform
that is not widely used, or affects only an out-of-date version of a
browser, you might simply decide to ignore the problem and let the
users affected by it cope with it on their own.

For example, earlier I suggested
defining an
onmouseout event handler to correct for the fact
that Netscape 2 and 3 for Windows do not correctly clear the status
line. Unfortunately, the onmouseout event handler
is not supported in Netscape 2, so this workaround won't work
for that platform. If you expect your application to have a lot of
users who use Netscape 2 on Windows and you think that it is really
important to get that status line cleared, you'll have to
develop some other workaround. You could use
setTimeout( )
in your onmouseover event handler to arrange for
the status line to be cleared in two seconds. But this solution
brings problems with it: what if the mouse is still over the
hypertext link and the status line shouldn't be cleared in two
seconds? In this case, a simpler approach might be to simply ignore
the problem. This approach can easily be justified, because
Netscape 2 is by now well out of date;
any users still relying on it should be encouraged to upgrade.


20.1.7 Fail Gracefully


Finally, there


are some incompatibilities that cannot
be ignored and cannot be worked around. In these cases, your program
should work correctly on all platforms, browsers, and versions that
provide the needed features and fail gracefully on all others.
Failing gracefully means recognizing that the required features are
not available and informing the user that he will not be able to use
your JavaScript program.

For example, the image-replacement technique we saw during the
discussion of images in Chapter 14 does not work in
Netscape 2 or Internet Explorer 3, and there is really no workaround
that can simulate it. Therefore, we should not even attempt to run
the program on those platforms; instead, we should politely notify
the user of the incompatibility.

Failing gracefully can be harder than it sounds. Much of the rest of
this chapter explains techniques for doing so.

/ 844