views:

1062

answers:

7

In one of my Web Development classes we where asked to create a script that detects NE4,NE6+,IE4,IE6+ Browsers that display a compatable CSS script for each browser.

he gave us an article to read about these and the article mentioned this site

one of the students said this

The best choice for javascript compatibility is to test for browser capabilities when you want to do something. One of the main reasons for this is that in the future, more and more browsers will be created.

Now my questions is this which way is the best way to detect the users browser object detection or using the Navigator Object?

+4  A: 

The best way is to avoid using browser dependent code as much as possible, but where absolutely necessary, use code that has been proven correct written by people who know a lot more than you and I. I would suggest JQuery, as that's my library of choice, but there are plenty of others out there (YUI is popular, as is Scriptilicious, etc). Google JQuery to get started. Also, google 'John Resig at Google' to see if you can find a talk he did where he discusses some of the techniques he uses to detect browser capabilities. It's very clever, as it adapts as browsers fix their legacy issues.

Travis
A: 

The best way is to not detect it, but to use a cross-browser-compatible library like jQuery. This also has a lot of other advantages in terms of expressiveness.

paxdiablo
Too bad until recently jQuery was cross browser due to browser sniffing.
Ionuț G. Stan
Your point being what, exactly? That I should just duplicate the way jQuery works but not use the rest of it? The advantage of using jQuery is that you don't need to care what browser you're using. The hard work's been done for you (and you get the bonus stuff as well).
paxdiablo
+4  A: 

The standard way to detect what browser is used is to check the user agent supplied.

var BrowserDetect = {
    init: function () {
     this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
     this.version = this.searchVersion(navigator.userAgent)
      || this.searchVersion(navigator.appVersion)
      || "an unknown version";
     this.OS = this.searchString(this.dataOS) || "an unknown OS";
    },
    searchString: function (data) {
     for (var i=0;i<data.length;i++) {
      var dataString = data[i].string;
      var dataProp = data[i].prop;
      this.versionSearchString = data[i].versionSearch || data[i].identity;
      if (dataString) {
       if (dataString.indexOf(data[i].subString) != -1)
        return data[i].identity;
      }
      else if (dataProp)
       return data[i].identity;
     }
    },
    searchVersion: function (dataString) {
     var index = dataString.indexOf(this.versionSearchString);
     if (index == -1) return;
     return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
    },
    dataBrowser: [
     {
      string: navigator.userAgent,
      subString: "Chrome",
      identity: "Chrome"
     },
     {  string: navigator.userAgent,
      subString: "OmniWeb",
      versionSearch: "OmniWeb/",
      identity: "OmniWeb"
     },
     {
      string: navigator.vendor,
      subString: "Apple",
      identity: "Safari",
      versionSearch: "Version"
     },
     {
      prop: window.opera,
      identity: "Opera"
     },
     {
      string: navigator.vendor,
      subString: "iCab",
      identity: "iCab"
     },
     {
      string: navigator.vendor,
      subString: "KDE",
      identity: "Konqueror"
     },
     {
      string: navigator.userAgent,
      subString: "Firefox",
      identity: "Firefox"
     },
     {
      string: navigator.vendor,
      subString: "Camino",
      identity: "Camino"
     },
     {  // for newer Netscapes (6+)
      string: navigator.userAgent,
      subString: "Netscape",
      identity: "Netscape"
     },
     {
      string: navigator.userAgent,
      subString: "MSIE",
      identity: "Explorer",
      versionSearch: "MSIE"
     },
     {
      string: navigator.userAgent,
      subString: "Gecko",
      identity: "Mozilla",
      versionSearch: "rv"
     },
     {   // for older Netscapes (4-)
      string: navigator.userAgent,
      subString: "Mozilla",
      identity: "Netscape",
      versionSearch: "Mozilla"
     }
    ],
    dataOS : [
     {
      string: navigator.platform,
      subString: "Win",
      identity: "Windows"
     },
     {
      string: navigator.platform,
      subString: "Mac",
      identity: "Mac"
     },
     {
         string: navigator.userAgent,
         subString: "iPhone",
         identity: "iPhone/iPod"
        },
     {
      string: navigator.platform,
      subString: "Linux",
      identity: "Linux"
     }
    ]

};
BrowserDetect.init();

http://www.quirksmode.org/js/detect.html

TheTXI
+1 as this is the one answer most likely to actually help him with his assignment.
Paolo Bergantino
UA based checking is poor in general, as you end up blocking browsers regardless of whether they fix bugs or not, don't work with new browsers, etc. A great example is that Chrome has to spoof as Safari for a number of sites due to sites that whitelist good browsers, vs. blacklisting the bad.
olliej
@Olliej: You are going to vote down an answer that specifically applies to the question at hand, when the question itself is a homework assignment. I highly doubt the teacher is going to be happy when the student comes back and says "you shouldn't do it that way" instead of doing what he was told.
TheTXI
Also, you are far better off to search for WebKit than Safari, as that way you get all WebKit based browsers (Apple ships WebKit as a system framework, so there are a few that use that, and a few others with custom builds), there are the gtk, qt and wx ports, and the chrome, android, and S60 forks.
olliej
+1  A: 

tho deprecated in 1.3.2 jQuery.browser() will return useful info ... also see jQuery.support()

Scott Evernden
+1  A: 

Honestly, if you're trying to detect the browser you're attacking the wrong problem. My advice would be to detect the features that you want to use and degrade based on that. For example, if you need to create an XMLHttpRequest something similar to the following will work:

  var xhr = null;
   if (typeof(XMLHttpRequest) !== 'undefined')
      xhr = new XMLHttpRequest(...);
   else if (typeof(ActiveXObject) !== 'undefined')
      xhr = new ActiveXObject('Microsoft.XMLHTTP');

   if (xhr != null)
      ...do something with it
   else
      throw "No XMLHttpRequest";

This approach allows your applications to grow as the browsers start to support more features. Obviously, it goes without saying that these sorts of checks should be abstracted away in a function somewhere so as not to litter your code with the same checks over and over again.

However, if you're able to use an Ajax library like JQuery, Prototype, Dojo, YUI, etc that's probably your best bet as they already have the abstractions built in.

Bryan Kyle
-1, he said in his question this is for class, there's no reason to jump at it for "attacking the wrong problem." It's an assignment.
Paolo Bergantino
@Paolo: I agree. I see this way too often on this site where people answering a question will attempt to steer the OP on the road they want them to take instead of just answering the question as it was proposed.
TheTXI
I have to disagree - it's worth knowing that you're asking the wrong question. It sounds like his lecturer doesn't have much real-world experience, or is not putting it to use. Bryan's approach is 100% spot -on, except that other people (read JQuery) have already done it :-).
Travis
+2  A: 

In one of my Web Development classes we where asked to create a script that detects NE4,NE6+,IE4,IE6+

Your web development class is hopelessly, laughably out of date.

Back in the days when Netscape4 and IE4 were common browsers, it was often necessary to sniff the browser type and serve them different stylesheets and scripts, because their support for styles and DHTML features was so very different.

These days the baseline browser, the lowest-quality one that you have to worry about, is firmly IE6. Almost no-one is using anything lower than that, because IE6 came with XP and the use of un-upgraded Win2K and Win9X boxes is vanishingly small. Certainly no-one in the universe is using IE4 or the awful Netscape 4; very few current web sites will even work on them.

Thanks to web standards, all the other browsers you might want to target (IE7+, Firefox2+, Opera, Safari, Chrome, Konqueror) are generally close enough to intercompatibility that you will rarely need to do much browser detection. IE6 does demand some care, but generally if you use Standards Mode you can get by with a few CSS hacks (specifically, “* html”) and some capability-sniffing in scripts, rather than have to serve up completely different content for it.

Now my questions is this which way is the best way to detect the users browser object detection or using the Navigator Object?

Object/method detection.

Avoid the navigator object whenever possible; it often lies for compatibility purposes, and scanning strings to try to work out browser names can easily trip up on unexpected tokens in the user-agent string.

In the event when you need to detect IE6 specifically (which is by far the most common browser to have to detect and add workarounds for), and there's no suitable way of capability sniffing, it's better to use conditional compilation than navigator.userAgent processing.

bobince
Yea I know this course is kinda lame because of that but it's a dumb assignment for class but what can I do lol
Ender
In that case the question is not so much “What is the Best way to do Browser Detection in Javascript?” as “What stupid thing do I have to do to satisfy my lecturer?” :-)
bobince
A: 

I built a simple Firefox Mac User Agent Detect that writes specific CSS. http://www.combsconsulting.com/code-firefox-mac-hack.html