Object detection

Opera 6 says it supports createElement though it cannot actually add the created element to the document. Opera 7 supports createElement correctly. There's no way to filter out older Opera's, though, except for a browser detect. So I don't do anything.

Fairly soon you will notice that certain features of JavaScript do not work in certain browsers. If you want to use an advanced bit of script, you first have to check whether a browser supports the objects you want to use. This page explains how to do it.

First I give some general info and rules, then I give some information about common effects that are not supported by some browsers and ways to detect support.

Browser detection - No

If you want to know whether the browser that views your page supports certain objects you want to use in your code, you should never EVER use a browser detect. Sure, you know that this–and–that browser will support your code while such–and–so browser won’t. But how about other browsers, obscure browsers?

While browser detection works well enough for 90% of your visitors, some obscure browsers won't be treated correctly and browsers that appear after you've written the page may not be adequately covered either. The results would be either a stream of error messages or a script that isn't called while the browser can easily handle it. In both cases, you're cheating your end users and coding incorrectly.

Case study: mouseovers

An old case study will clarify things. Nowadays this particular example isn't much of an issue any more, but the principles are still valid.

It is a well known fact that Explorer 3 does not support the document.images array that is vital for the mouseover script. Thus we have to prevent the script from being executed in Explorer 3. A solution would be to do a browser detect for Explorer 3 and not exceute the functions if the user views your page with Explorer 3.

However, on most OS's Netscape 2 doesn't support document.images either. If you just do a browser detect for Explorer 3, you leave the Netscape 2 users helpless to a stream of errors.

So why not add Netscape 2 to your browser detect? Because it doesn't solve anything.

Netscape 2 on OS/2 is almost completely Netscape 3 compatible and it can handle mouseover effects. Nonetheless the effects usually aren't visible because the web developers used a browser detect and decided that Netscape 2 couldn't possibly support mouseovers. Thus they cheated their end users of a bit of interaction without good reason. A proper object detect would have avoided these problems.

Finally, more and more browsers give the user the possibility to adjust his browser identification string to anything he likes (see the browser detect page). Therefore it's quite possible that a browser detect doesn't recognize his browser and therefore excludes it from functionality that it can handle without trouble. Here, once again, you cheat your users of an extra bit of interaction. Even worse, it's bad coding.

Are JavaScript version numbers more reliable?

JavaScript versions - No

When devising JavaScript, Netscape was fully aware that future browsers would support more objects than old ones, and that web developers should be able to distinguish between old and new browsers.

The original plan was that they would check the JavaScript version number. Such-and-such object was only to be supported by JavaScript 1.something. Use the JavaScript version number in your <script> tag and browser that don’t support the object won’t execute the script.

However, when Microsoft entered the market, this idea went to shambles. Although early Netscape 4 and Explorer 4 versions both supported JavaScript 1.2, not even the most powerful fantasy can imagine them supporting the same JavaScript 1.2 . With this the version numbers became obsolete and irrelevant to object detection.

So don’t use JavaScript version numbers. They’re useless.

Object detection - Yes

Instead, we simply look if the browser supports the object (method, array or property) we want to use. Let’s continue with the mouseover example. This script relies on the document.images array, so first and foremost we'll have to detect if the browser supports it. This is done by

if (document.images)
{
	do something with the images array
}

Now you have a fail safe method of seeing if any browser can handle mouseovers. The if-statements checks if the array document.images exists. If it does (document.images) is true and the script is executed. If the images array doesn't exist it becomes false and the script is not executed.

Another common detect is for window.focus. This is a method (a command by which you tell JavaScript to do something for you). If we want to use the method, we'll have to check first if the browser supports it.

Note the correct way of doing this: you ask for the method without brackets. This code

if (window.focus)

means: "If the focus method is supported", while this code

if (window.focus())

means: "If you can put the focus on the window" and assumes that focus is supported. If it isn't, this line of code creates errors. The brackets () actually execute the focus command, which is not what we want in this case. So we check it without the brackets (see if it exists) and only when the browser passes the check we actually execute the command by adding brackets:

if (windows.focus) window.focus()

The point

So the whole point is that if you want to use the array document.images, first check if it is supported. If you want to use the focus method of the window, first check if it is supported.

If you always use object detection, your scripts will never generate any error messages, although they might not work in certain browsers.

Not supported

Finally some info about ancient effects that need object detection.

document.images

Netscape 2 and Explorer 3 on Windows: no support

Explorer 3 on Mac: says that it supports document.images but doesn't actually do any image swaps. Doesn't give errors, though.

Netscape 3.01 (and some Hotjava 3's) does support it but has another problem: in these browsers, the images are not really changed, but rather placed on top of each other. This problem is solved in Netscape 3.04 and higher. The newer Hotjava 3 that I downloaded at home seems to have solved this bug too.

Opera 3.60, finally, has problems with cross-frame mouseover scripts.

Your browser does support document.images.

document.images is the JavaScript array that gives access to the images in a page. If you want to add an onMouseOver or an onClick image-swap effect to your pages you use document.images, which means that browsers that do not support it don't do the image swap and give lots of errors.

Fortunately you can avoid errors by always writing functions that do something with document.images like this:

if (document.images)
{
	script here
}

Thus the script is only executed when the browser supports document.images. Browsers that don't support it don't get the effect but no errors either.

window.focus

Hotjava 3 has buggy support. The example on this page works, but others on this site don't. I have no idea what the problem is.

Netscape 4 on Linux does support it, but when you lay the focus on something that's not currently on the screen, the page does not scroll to show the element you laid the focus on. This is very confusing.

Opera 3 and 4 refuse to lay the focus on another window when you're cross-window JavaScripting, although in other circumstances it does support the focus. This is solved in Opera 5, except on Linux.

Opera 5 on Mac says it supports focus() but in fact does nothing.

A useful feature of JavaScript is the ability to place the focus on a certain window or a certain element within that window, for instance a form element.

If you load pages into pop-ups it is also useful to put the focus on the pop-up so that the user can follow what's happening. This is in no way necessary for the page to function, but it is a nice extra service.

To prevent errors, always call the focus like this:

if (window.focus) window.focus()

I first thought that Netscape 2 and Explorer 3 didn't support focus at all. However, it turns out that Netscape 2 does support focus, just not on the window level. It is, however, perfectly possible to focus on form fields.
Jeff Howden, who corrected the mistake, proposes not to use object detection for form fields at all, since all known browsers support the focus method on them. I think he’s right, so when you want to use the focus method on form fields, you don’t have to use an object detection.

Therefore I do not use object detection at all in my text field checking script, where I put the focus on a form element.

DHTML

DHTML is supported by Netscape 4+, Explorer 4+, Opera 5, Escape 4, Konqueror, iCab and Omniweb.

Dynamic HTML is the changing of the style declarations of an HTML element by means of JavaScript. For a longer and more complete description of DHTML, see the Introduction to DHTML.

To support DHTML, the browser needs to support one of the intermediate DOMs. Here object detection is extremely important, since there are no less than three advanced DOMs and you have to find out which one the browser supports and lead it to the correct bit of code. For a general check “Can this browser do DHTML” I use:

if (document.getElementById || document.all || document.layers)
{
	browser can handle DHTML
}

In this case we check for three possible objects, since there are currently three sets of code a browser may support. Only one of the three objects needs to be supported for the DHTML to work, so we use the Boolean || (OR) operator.

When we come to the specific script, we have to give special instructions to each DOM.
(See the DHTML micro-API page for more details)

Here, too, we could use a browser detect but since all kinds of new DHTML-capable browsers are entering the market and at the moment it is unclear which DOM they will support, it would be dangerous to do so. Don't check if the browser is Explorer 4, check if the browser can handle document.all. Much safer in the long run.

W3C DOM

The advanced parts of the W3C DOM are only supported by Mozilla, Explorer 5 and Konqueror.

Unfortunately Opera 6 pretends it supports advanced parts of the W3C DOM, but can’t actually handle scripts.

The W3C DOM is about creating and removing HTML elements, allowing you to modify your HTML document on the fly. Of course, first you need to find out if the browser actually supports the W3C DOM. The general detect for this is

if (document.getElementById)

If the browser passes this test, you know that it supports at least parts of the W3C DOM.

However, for the really new scripts this is not enough. Opera 5, for instance, supports enough of the new DOM to do DHTML but not enough to support really advanced scripting. Therefore when you really want to use the new scripting, you should start with this object detect:

if (document.getElementById && document.createElement)

This one first checks for the W3C DOM and then for the presence of the crucial createElement() method. If it isn't supported the browser is not sufficiently advanced for true W3C DOM scripting. Explorer 4 supports document.createElement too (though it works differently from the W3C method), but we don't want it to execute the scripts. Therefore we also have to check for getElementById.