What browser is that?
If the world were a simple place, the W3C’s standards would always have provided the full range of layout tools Web designers wanted to use, and all browsers would have supported the full specifications of the HTML standards that the W3C laid down from the beginning. Unless you’ve just got back from ten years on a desert island it will not be news to you that this is very much not the case.
In the real world, you cannot even depend on Netscape’s proprietary tags working predictably in Netscape. (Not, by the way, a reference to Netscape 6, although it certainly could be.) The obvious result of this is that there are two possible approaches Web designers might take.
A designer might craft his pages for one browser, and to hell with any other. The only time this is a sensible approach is when the site in question is being designed for an intranet, a circumstance in which the designer might reasonably be expected to know what browser/platform combinations will be used to access the site.
On the Internet, this approach is very bad, because it can drive away potential customers in huge numbers. If, as is sometimes the case, a designer creates a site either deliberately or unknowingly Microsoft IE-specific, perhaps up to 30% of the site’s visitors will be turned away. If — and it does sometimes still happen — the site is Netscape-specific, there is a good chance of 55–75% of its visitors being shut out.
The second approach, of course, is to write code to handle most browsers — at the very least, the most common versions of the two big names. (Let me emphasise, that is very much a bare minimum.) Again, there are two approaches to doing this.
You can write a page, one which will function across the board without too much variation because you have used standard HTML and no proprietary elements. This is an appealing idea and most of the time the best approach. It does not necessarily mean that you are stuck with what I have heard a couple of people describe as “Ye Olde Webbe Page”.
The problem is that sometimes you may want to use a design approach which won’t work in every browser. Perhaps you want to make use of <iframe> — which is part of the HTML standard since HTML 4, but isn’t supported by Netscape 4. Perhaps you want to make extensive use of CSS, beyond the level at which you can depend on Netscape 4’s results.
Unless you actually want to exclude users of other browsers, you are faced with in some way writing different code for different browsers.
In the case of the <iframe> element, it can be used to insert code which will work in MSIE 4 & 5 and Netscape 6. Alternative content for browsers which don’t support <iframe>, including Netscape 4, can be placed between <iframe> and </iframe>. A browser which supports <iframe> will ignore (or perhaps should might be more accurate) the content between its opening and closing tags; a browser which doesn’t will ignore <iframe> and render the code it encloses.
However, such an approach may not be adequate or appropriate in every circumstance. Sometimes it the only solution is to have two (or more) sets of pages with JavaScript used to redirect the user to the suitable part of the site depending on what browser is being used.
How do you go about detecting which is the browser in use? One common method is to check for properties of the document like so:
if (document.all) {
//code to be executed in IE
} else if (document.layers) {
//code to be executed in Netscape
}
Common, but not a good approach. It is appropriate to use this if writing a script which actually uses document.all or document.layers, but not to determine the identity of a browser.
Perhaps it is unlikely that anything other than Netscape 4.x will have document.layers, but MSIE is not the only browser which has document.all. Assuming that a browser which does possess document.all behaves identically to MSIE 5 across the whole range of its functionality is extremely risky.
If you want to find out what browser is in use, you need to test for the browser.
This is relatively easy to do using two properties of the navigator object: navigator.appName and navigator.appVersion.
The appName property returns the official name for the browser. In the case of Internet Explorer, this returns ‘Microsoft Internet Explorer’; with Netscape Navigator or Communicator it returns ‘Netscape’.
The appVersion property returns the version number plus some more information. However, the version number returned may not be the number you expect. To see what I mean, look at the information returned from some browsers using navigator.appVersion:
| IE 5.0 (Windows) |
4.0 (compatible; MSIE 5.0; Windows 98) |
| IE 5.0 (MacOS) |
4.0 (compatible; MSIE 5.0; Macintosh; I; PPC) |
| Netscape 4.7 (MacOS) |
4.7 (Macintosh; I; PPC) |
| Netscape 6 (MacOS) |
5.0 (Macintosh; en-US) |
| iCab preview 2.1 |
0.21 (compatible; iCab 0.21; Macintosh; I; PPC) |
The version number returned may not be the same one you expect, but in general this is not too much of a problem. Rarely do you need to differentiate between IE 4 and IE 5, for example. The important differentiation is usually between fourth generation browsers and older browsers, because the technology designers wish to make use of that requires browser-detection scripts tends to be combinations of CSS-P and JavaScript — which means Netscape and IE versions 4 and above.
Using the parseFloat() method, it is easy to extract the numerical value of the version number. In your browser-checking function, the following line would assign the numerical value of the browser version to the variable navVer:
navVer = parseFloat(navigator.appVersion)
This is to be preferred over parseInt() because of cases like the iCab preview release referred to above, where the use of parseInt(navigator.appVersion) would return 0.
Note that if the numbers to the right of the decimal point evaluate to zero, parseFloat() will return an integer: thus parseFloat(navigator.appVersion) will return 4.7 with Netscape 4.7, but 5 with Netscape 6.
Determining which browser is in use can be a little more tricky. The following line will take the string returned by navigator.appName and assign it to the variable navNam:
navNam = navigator.appName
To find out the browser identity, use the indexOf() method to determine whether or not a given string occurs in navNam. The first thought, without looking any further, might be to try to use it like so:
if (navNam.indexOf('Microsoft')) {
//code if IE
} else if (navNam.indexOf('Netscape')) {
//code if Netscape
} else {
//code if neither
}
This seems obvious and simple enough — except that it doesn’t work.
The method string.indexOf() does not simply return a true/false value, it returns a number indicating the position at which the string tested for occurs within the string being tested (in this case, navNam), beginning at zero.
If the string is not found, the method should return -1. This is how to put the function to work:
if (navNam.indexOf('Microsoft') != -1) {
//code if IE
} else if (navNam.indexOf('Netscape') != -1) {
//code if Netscape
} else {
//code if neither
}
That is, if the value returned by string.indexOf() is anything other than -1, then the search string is found in the main string.
Another problem creeps in with some versions of Netscape 2 and 3. Apparently certain versions of these browsers don’t return -1 if the string is not found, they return an empty string. This may be something you wish to test for, and could easily be done using
if (navNam == "") {
//etc.
}
You will note from the if … else construct the script checks first to see if “Microsoft” occurs within navNam. The more steps that have to be executed, the longer the script takes. It’s probably not going to make all that much difference with today’s processor speeds, and certainly not with a small script like this. However, it is good sense and practice to put the most likely value first, and these days that means Internet Explorer. Next most likely is Netscape; if you want to check for anything else, all the rest are pretty much on a level.
Also note, and this is very important, that at the end of the if … else construct there is a catch-all option to tell the script what to do if the browser happens to be neither Internet Explorer nor Netscape.
A lot of people forget this, but surfers do use browsers other than those two. I have made a point of mentioning iCab to get this point over, and there are plenty of others besides it. If you don’t provide for that eventuality, users of other browsers are liable to find themselves staring at a blank browser window. Not for long, though — they’ll go away and they won’t come back.
Unless you prepare for it, a blank screen can also hit people who happen to be surfing with JavaScript disabled. A lot of people do this and there is no use complaining about it.There may be good reasons for them doing so. If they happen to be using Netscape 3, for example, it makes sense as its JavaScript implementation seems to include the logic “IF JavaScript executed THEN crash browser”.
There is no excuse for not coping with non-JavaScript-enabled browsers. All it takes is a <noscript> element enclosing text links that fit the options you want: IE 4 and above, NS 4 and above, anything else — that sort of thing.
There are two important points about using <noscript>. Again, remember not to exclude the users of browsers other than Internet Explorer and Netscape. Also, if your Netscape 4 pages depend on CSS, you need to know when preparing your links that disabling JavaScript in Netscape 4 also disables CSS support.
So, finally, here is a piece of JavaScript which will check the browser in use and redirect the user accordingly. It would be called like so:
<body onLoad="checkBrowser('ieURL','nsURL','altURL')">
Here ieURL is the address of a page to send the user to if using IE 4 or higher (and which we’ll assume also to be suitable for Netscape 6), nsURL if a Netscape 4 version, and altURL if IE 3 or Netscape 3 or lower, or some other browser.
To handle the case where the URL includes non-alphanumeric characters — something you should try to avoid — the function unescape() is used to ensure the URL is passed as a plain string.
<script type="text/JavaScript">
function checkBrowser(ieURL,nsURL,altURL) {
var navNam;
var navVer;
var goURL;
navNam = navigator.appName;
navVer = parseFloat(navigator.appVersion);
if (navNam.indexOf('Microsoft') != -1 ) {
if (navVer >= 4) {
goURL = ieURL;
} else {
goURL = altURL;
}
} else if (navNam.indexOf('Netscape') != -1) {
if (navVer >= 5) {
goURL = ieURL;
} else if (navVer < 4) {
goURL = altURL;
} else {
goURL = nsURL;
}
} else {
goURL = altURL;
}
if (goURL) {
window.location = unescape(goURL);
}
}
</script>
© DC 2000. All rights reserved.


