5.7 Detecting Object Property and Method Support
NN 2, IE 3
5.7.1 Problem
You want scripts
to run on all browsers that support the object properties and/or
methods that your scripts address, and to degrade gracefully in other
browsers.
5.7.2 Solution
Surround the script statements that
reference potentially incompatible object properties or methods with
if statements that test for the existence of the
objects and their properties or methods. The items you test for can
belong to core JavaScript language objects, as well as to DOM
objects. Testing for the existence of a property or method is a
little more complicated than testing for the object alone. If your
condition expression references a property of a nonexistent object, a
script error results. Therefore, you must precede your
property/method test with a test for the object (assuming the object
is not one that is fully backward-compatible).
if (objectTest && objectPropertyTest) {
// OK to work with property
}
This combination works smoothly because if the first condition test
fails, JavaScript short-circuits the rest of the expression,
bypassing the second condition.
It is not advisable, however, to use the simple existence test for an
object's property in an if
condition. The main reason is that some legitimate property values
are zero or empty strings. A conditional test with these values
evaluates the same as false, which gives an
incorrect reading about support for the property (see Recipe 4.6).
The best way around this problem is to test for the data type of the
property being something other than undefined:
if (objectReference && typeof objectReference.propertyName != "undefined") {
// OK to work with property
}
References to object methods take
the same form as references to functions: the name of the method
without the parentheses. If the method exists, the reference
evaluates to a valid object type and the conditional test succeeds:
if (objectReference && objectReference.methodName) {
// OK to work with method
}
For example, to protect scripts written with W3C DOM
element-referencing from tripping up older browsers, you can wrap
function execution inside conditions that test for the existence of
the document.getElementById( ) method:
function myFunction( ) {
if (document.getElementById) {
// OK to use document.getElementById( ) here
}
}
To save some bytes on the page and extraneous expression evaluation,
you can also set a Boolean global variable as the page loads to use
in later condition statements:
var isW3 = (document.getElementById) ? true : false;
...
if (isW3) {
// OK to use document.getElementById( ) here
}
5.7.3 Discussion
Be careful about the assumptions you make when you qualify a browser
for an object and one of its properties or methods. For instance, it
would be a mistake to assume that because the browser indicates
support for the document.getElementById( ) method
that it supports the rest of the W3C DOM Core module objects,
properties, and methods. With experience, however, you will gain the
knowledge that all browsers that recognize the all-important method
also know about the basic element node properties, such as
nodeType, nodeName, and
nodeValue. Again, a good DOM reference will help
you with those kinds of decisions.
Don't be afraid to nest multiple levels of object
and property/method detection in a function. You can see examples of
this when processing events for the incompatible IE and W3C event
models (Recipe 9.1). But always make sure that your functions are
structured in such a way that any one condition failure is handled
gracefully so that no script errors accrue in the absence of support
for your desired object, property, or method.
The
W3C DOM
specification includes facilities to help scripts know what level of
support is offered by the browser. Every element object has an
isSupported( ) method, whose parameters let you test
for the browser's support of various W3C standards
or DOM modules. The module names available for testing as of DOM
Level 2 are Core, XML, HTML, Views, StyleSheets, CSS, CSS2, Events,
UIEvents, MouseEvents, MutationEvents, HTMLEvents, Range, and
Traversal. In theory, if the browser fully supports the required
portions of a module, the isSupported( ) method
returns a value of true:
if (myElem.isSupported("CSS", "2.0")) {
myElem.style.color = "green";
}
But this test is not rigorous enough for most scripters. The
standards contain numerous optional features, whose omission still
allows a browser maker to claim full conformance with the standard.
The only way to assure complete support for modern scriptable
features is via the more explicit object, property, and method
condition testing.
5.7.4 See Also
Recipe 5.6 for detecting object support; Recipe 4.6 for special
condition expressions that evaluate to true and
false; Recipe 9.1 for nested object detection in
event processing.
|