Free Web tutorials covering HTML, CSS, JavaScript, and DHTML from beginner to advanced. Free downloads and developer resources. Personalized help via email, form, and chat.

free, web, tutorials, HTML, html, CSS, css, stylesheet, cascading stylesheet, Javascript, javascript, JavaScript, DHTML, dhtml, beginner, advanced, web development, web page, web site, free web tutorial, free HTML tutorial, free CSS tutorial, free css tutorial, free cascading stylesheet tutorial, free stylesheet tutorial, free javascript tutorial, free DHTML tutorial, free HTML class, free CSS class, free stylesheet class, free cascading stylesheet class, free javascript class, free DHTML class">

Free Web tutorials covering HTML, CSS, JavaScript, and DHTML from beginner to advanced. Free downloads and developer resources. Personalized help via email, form, and chat. free, web, tutorials, HTML, html, CSS, css, stylesheet, cascading stylesheet, Javascript, javascript, JavaScript, DHTML, dhtml, beginner, advanced, web development, web page, web site, free web tutorial, free HTML tutorial, free CSS tutorial, free css tutorial, free cascading stylesheet tutorial, free stylesheet tutorial, free javascript tutorial, free DHTML tutorial, free HTML class, free CSS class, free stylesheet class, free cascading stylesheet class, free javascript class, free DHTML class

<Code_Punk>'s

Beginning JavaScript Lesson 8:
Browser Detection

Code Tutorials



Site Development



Downloads



Help!!



Home

The Need For Browser Detection

There are many different browsers out there supporting a variety of Document Object Models (DOMs). These DOMs each require different JavaScript object references to access an object. This makes it essential that you know how to detect which browser a viewer is using and direct it to JavaScript code appropriate to that particular browser.

The most common need for browser detection is when we're using JavaScript to dynamically change an objects CSS styling. For example, changing a <div>'s "visibility:" property with JavaScript is what makes pop up menus appear and disappear. Newer browsers use one JavaScrpt statement to do this and older Netscapes use another. We need to know what browser is being used to direct it to the appropriate code.

We've not run across any "cross-browser" issues yet. I want you to understand browser detection before you need it. In this lesson we'll make this page that will tell you what browser is being used.

You will not need browser detection for every script you write, but you'll need it for a lot of them. The browser detection presented in this lesson is very complete and not needed in every situation. Don't let it scare you off.

The Players

There are four browsers/DOMs that you should consider when you code:

Microsoft Internet Explorer (IE) -- This is the big one. Depending on the survey, IE is used by at least 85% of all web surfers. On sites I monitor this goes up to 99%. If you want your page to be viewed by the bulk of people on the web, you must make sure your code works in IE.

Newer Netscapes (NS6, NS7) -- Netscape was the first popular browser and is still used by many, especially those using the Linux operating system. Netscape 7 is a complete overhaul of older Netscapes using the newest Mozilla rendering engine.

Older Netscapes (NS4 or less) - Many people still use a 4.x version of Netscape. It's a great browser, but just doesn't support many JavaScript objects. It's especially weak in support of dynamic CSS styling with JavaScript. But, it's still in use and you should keep it in mind.

Opera (Opera) - I think this is the neatest browser around and use it myself. It uses its own Mozilla-based rendering engine that's similar to newer Netscapes. There are plenty of differences, though. It's great to have because you can set it up to mimic IE and various Mozilla browsers. A great development previewing tool. Note that just because you set up Opera to imitate another browser, doesn't mean it uses the imitated browser's DOM.

Setting Up A Detection Page

Let me say at the outset that you rarely need to use browser detection this accurate. It is good, though, to know how it's done and what is going on. Now lets start making our example. Start out with a pretty basic HTML template and add a "document.write()" to display the browser name:

<html>
<head>
<title>Browser Detection</title>

<script language="JavaScript">

var browser = "";

</script>

</head>

<body bgcolor="#ffffff">

<h2>You are using the
<script language="JavaScript">
document.write(browser);
</script>

browser.</h2>

</body>
</html>

The above is a simple page that will print out the variable "browser" in an <h2> header. The variable "browser" is initialized in the <head> to a null (nothing) string. If run, "browser" would be null and no browser name would show up if the page were run.

Simple Object Detection

You rarely need to identify a specific browser, just its support for a particualar object or property. Many browsers may support the same property. A good example is "document.getElementById". This object is used to change CSS properties dynamically in JavaScript. Don't worry about using the statement now. We'll do plenty of that when we begin coding pop up menus.

For now just note that all modern browsers (IE5+, Netscape 7, and Opera) support this object. Older Netscapes (4.x) do not, they use a different syntax. So, we don't need to detect individual browsers in this case, just support for "document.getElementById"

Here's a sample of checking for "document.getElementById" support:

if (document.getElementById)
{code to use if supported}

else{code to use if not supported}

It's as simple as that. You just put the object reference in the parentheses of an IF statement. If the browser supports the object, the code will run. Otherwise, the ELSE code will run. You can check for any object with this scheme.

Conversely you can check to see if a browser does not support an object. To do this, just put an exclamation point in front of the object reference.

if (!document.getElementById)
{code to use if not supported}

else{code to use if supported}

Now lets use object detection to detect older Netscapes.

Detecting Older Netscape

This is the easiest of the browsers to detect. It is the only one that doesn't support the "document.getElementById" object. Don't worry about what "document.getElementById" is right now. Just note that all modern browsers support it. Older Netscapes (versions 4.x or less) do not.

Here's how to detect a lack of support for "document.getElementById":

<html>
<head>
<title>Browser Detection</title>

<script language="JavaScript">

var browser = "";

//detecting older netscapes
if (!document.getElementById){browser = "Old Netscape"}


</script>

</head>

<body bgcolor="#ffffff">

<h2>You are using the
<script language="JavaScript">
document.write(browser);
</script>
browser.</h2>

</body>
</html>

Pay particular attention to the exclamation point (!) preceding "document.getElementById" in the IF statement. That exclamation point (!) means "no" or "not". In this case it means that there no supported "document.getElementById" object. A sure sign that an older browser is being used. Netscape 4.x is the only older browser being used in any significant number.

Once detected, notice that we assign the variable "browser" to equal the string "Old Netscape". If the page was run in Netscape 4.x, it would display the string "Old Netscape". Other browsers would still show the null string value for "browser".

In practice, older Netscapes are usually not directly detected. Newer browsers supporting "document.getElementById" are detected and older Netscape code is put in an ELSE statement:

if (document.getElementById)
{code for modern browsers}

else {code for older Netscapes}

You'll see the above often when we learn to code pop up menus. For our example, we want to identify older Netscapes specifically and will be using the "(!document.getElementById)" version of detection.

Using indexOf()

The "indexOf()" method helps us find individual words or characters in a larger string. A string is a literal string of characters - letters, digits, special characters. Anything that's not a pure number, or boolean value, or function name, etc.

We'll be using it to analyze the string returned by "navigator.userAgent", but it's a powerful tool that can be used to analyze any string. Lets look at an example.

var string = "Code_Punk";
var what_position = string.indexOf("e");

In the above code we made a variable called "string" and set it to equal "Code_Punk". Below we set another variable, "what_position", to store the "indexOf()" value of the "e" character. This is a number indicating the positin of "e" in the string.

What happens in the last line of code is that the string "Code_Punk", stored in "string", is searched for the character "e" by the "indexOf()" method. When the first "e" is found, a number is returned to indicate its position. The count begins with the first character - "C" - which is in the zero position. Note that the counting begins with 0.

In our above example, "what_position" would equal 3. Remember that the counting begins at 0. Neat, huh. And, it doesn't stop there. You can search for whole substrings:

var string = "Code_Punk"; var what_position = string.indexOf("Punk");

The above would look for the whole string "Punk". Not just one character, but a whole substring. Note that capitalization is critical in these searches. It must be accurate.

The above would return the position of the first character of the substring we searched for. That would be the position of the "P" in this case - or 5. Remember that the count begins at 0 and that a number is returned.

Now what would happen if we searched for a character or substring that didn't exist in the overall string?

var string = "Code_Punk"; var what_position = string.indexOf("tiger");

The substring "tiger" doesn't exist in the string being searched. In this case, "indexOf()" would return a -1. This is very important because we can easily use "indexOf()" to detect whether or not a substring exists in a larger string.

If the "indexOf()" value is -1, the substring does not exist. If the value is 0 or higher, the substring does exist.

I'll bet you can think of many handy applications of this. For now we'll use it in our browser detection to analyze the "navigator.userAgent" string. We can find out if specific data exists by searching for substrings.

Detecting Opera

Opera is easy to detect because it's the only browser that uses the substring "Opera" in its "navigator.userAgent" string. Opera can be configured to spoof its "appName" as "Netscape" or "Microsoft Internet Explorer", but the "userAgent" will always contain the substring "Opera".

We need to do two things. First, we need to get the browsers "navigator.userAgent" string. Secondly, we need to search for the substring "Opera". We can use "indexOf()" for this search.

The "indexOf()" method can be used with any string. You put what you're searching for in the parentheses and in quotes. Now "indexOf() will return the position in the overall string that the substring begins. If the substring doesn't exist in the overall string, a value of -1 will be returned.

Here's an example using Opera's "userAgent":

if (navigator.userAgent.indexOf("Opera") > -1) ...

The detection begins by getting the "navigator.userAgent" string. Next, we add "indexOf()" to search for a substring. Now we put "Opera", the substring we're looking for, inside the parentheses - quotes included. Pay attention to capitalization like the capital "O" in "Opera".

Now the "userAgent" string will be searched for the substring "Opera". If the substring "Opera" exists, "indexOf()" will return the character position in the string where the substring begins. This would be the position of the "O". If the substring "Opera" does not exist, "indexOf()" will return a -1.

In short, if "Opera" is a substring of "userAgent", the "indexOf("Opera")" will be a value of 0 or greater (> -1). If the substring is not there, "indexOf()" will be less than zero (< 0).

There are all sorts of neat ways to use "indexOf()". It can search any string for any substring. It comes in really handy in analyzing a "userAgent" string for a substring. We'll be using it some more.

Now lets add our new Opera detection routine to our code:

<script language="JavaScript">

var browser = "";

//detecting older netscapes
if (!document.all){browser = "Old Netscape"}

//detecting Opera
if (navigator.userAgent.indexOf("Opera") > 0){browser = "Opera"}


</script>

The new code above will detect the Opera browser and set our "browser" variable to "Opera".

Detecting IE

We could detect IE using:

if (navigator.appName == "Microsoft Internet Explorer")...

OR

if (navigator.userAgent.indexOf("MSIE") > -1)...

The only problem with the above is that Opera can be set up to mimic IE by changing its "appName" and adding "MSIE" to its "userAgent". So we have to add detection for the substring "Opera" in "userAgent" not to be fooled. This time we'll be checking for the absence of "Opera" (< 0).

When we have to check for more than one condition in an IF statement, we connect the two comparisons with two ampersands (&) -- &&. We can make as many comparisons as we'd like in a single IF statement seperating each with &&.

When && is used, it means that all of the condition must be true for the code to run. If even one condition is false, the IF statements won't run.

if (navigator.appName == "Microsoft Internet Explorer" && navigator.userAgent.indexOf("Opera") < 0)...

The above checks for two things. First it checks to see if the "navigator.appName" is "Microsoft Internet Explorer". Secondly, it checks to make sure that "Opera" is not in the "userAgent" (< 0). Remember that if the substring "Opera" does not exist in the searched string, "indexOf()" will return -1. If both conditions exist, it means you're dealing with IE and not Opera imitating IE.

Notice how we checked for two things in one IF. We used two &&'s. This means that both statements must be true. Here's our new code added to our browser detector:

<script language="JavaScript">

var browser = "";

//detecting older netscapes
if (!document.all){browser = "Old Netscape"}

//detecting Opera if (navigator.userAgent.indexOf("Opera") > -1){browser = "Opera"}

//detecting IE
if (navigator.appName =="Microsoft Internet Explorer" && navigator.userAgent.indexOf("Opera") < 0){browser = "IE"}


</script>

Detecting Newer Netscapes

Newer Netscapes are the last class of browser we need to detect. We can start out by simply checking the "appName":

if (navigator.appName == "Netscape")...

The above would immediately eliminate IE. It limits us to all Netscapes and Opera imitating Netscape. To eliminate older Netscapes, we can use "document.getElementById" or "document.all" support. Newer Netscapes support "document.getElementById" and "document.all", but older Netscapes don't - as we've previously learned

if (navigator.appName == "Netscape" && document.all)...

The above would limit us to either newer Netscapes or Opera set to imitate Netscape. We eliminate Opera by searching the "userAgent" as we did with IE:

if (navigator.appName == "Netscape" && document.all && navigator.userAgent.indexOf("Opera") < 0)...

The above checks for three things: "appName" of "Netscape", support for "document.all", and no "Opera" substring in "userAgent". This leaves us with newer Netscapes - NS6 and NS 7. Lets add this final detection to our code:

<script language="JavaScript">

var browser = "";

//detecting older netscapes
if (!document.all){browser = "Old Netscape"}

//detecting Opera if (navigator.userAgent.indexOf("Opera") > 0){browser = "Opera"}

//detecting IE
if (navigator.appName =="Microsoft Internet Explorer" && navigator.userAgent.indexOf("Opera") < 0){browser = "IE"}

//detecting newer Netscapes
if (navigator.appName == "Netscape" && document.all && navigator.userAgent.indexOf("Opera") < 0){browser = "Newer Netscape"}


</script>

Summary & Exercises

Whew! That was a lot to cover. At least it was worth the trouble and you learned how to use "indexOf()", too. The browser detector we just built is very specific. This level of detection is almost never needed. I'll bet you're glad of that.

If our page were to include functions that needed to know which browser was used, we could use the variable "browser" and the values we assigned above to make detection easier: if (browser == "IE") would be all we needed to check if our browser were Internet Explorer, for example. Once set up, our detection scheme can make coding simpler for subsequent functions.

Here's a quick breakdown of the detection schemes:

Older Netscape - if (!document.getElementById)...

Opera - if (navigator.userAgent.indexOf("Opera") > 0)...

Internet Explorer - if (navigator.appName == "Microsoft Internet Explorer" && navigator.userAgent.indexOf("Opera") < 0)...

Newer Netscapes - if (navigator.appName == "Netscape" && document.getElementById && navigator.userAgent.indexOf("Opera") < 0)...

One piece of good news is that you don't always have to check for Opera imitating another browser. If it is imitating a browser, the code for that browser may well work in Opera. And, of course, many scripts will run in all browsers without any detection needed at all.

Another thing to consider is the dominance of IE. Some developers just code for IE and let some things slide in the other browsers. Only critical functions are coded for all browsers.

Now make a page that brings up a custom alert() box for each major browser type.



To Next Beginning JavaScript Lesson

Back To Beginning JavaScript Index