According to Microsoft and best client-side scripting techniques, one shouldn't use the browser sniffing using navigator.appName, navigator.userAgent, attachEvent and detachEvent etc. to provide cross-browser compatibility. Rather use Feature and Behavior detection to resolve the compatibility. More details on MSDN magazine.

Exampli gratia:

if(navigator.appName == "Microsoft Internet Explorer") { /* browser sniffing */
    xhr = new ActiveXObject("Microsoft.XMLHTTP");

Instead use:

if(typeof(XMLHttpRequest) == "undefined") { /* feature detection */
    xhr = new ActiveXObject("Microsoft.XMLHTTP");

When I used Compact Inspector with Fiddler to diagnose stackoverflow.com, it showed 5 errors for browser sniffing and a notification (old version of jQuery is used).

Compact Inspector result for Stackoverflow.com

Please incorporate the indicated changes all over the stackexchange ecosystem.

  • 9
    If it ain't broke, don't fix it. This is not an actual problem you're facing. – Ry- Jul 3 '12 at 1:34
  • I don't run Windows so I can't check this myself (not that I'm sure I would anyway. This post would be more valuable if it had details. Relying on external links should be avoided.). However, I think those warnings are being triggered by jQuery. Stack Exchange doesn't use ActiveXObject directly... and jQuery's use of ActiveXObject does use feature detection, it just doesn't use the same pattern as MS is recommending. – Jeremy Jul 3 '12 at 1:38
  • 9
    "Required changes"? Really? – meagar Jul 3 '12 at 1:39
  • @JeremyBanks, you can certainly use compact inspector. Its independent of OS. Its actually a JS file. If you know how to work with console in any browser, yes you can inject a js file in the visible page. – vulcan raven Jul 3 '12 at 1:57
  • 8
    This almost feels like those popups that say "you have 50 pieces of malware...click here to clean!" – simchona Jul 3 '12 at 2:00
  • @meagar, yeah that's right. The preferred way is to avoid UA sniffing. As a website designer you should have known that.. – vulcan raven Jul 3 '12 at 2:00
  • @vulcanraven The page says that is must be run before any other scripts and using it as a bookmarklet does not work. It implies that what you say is not possible. Perhaps it's possible to stop the JS engine before the first script runs by using a DOM breakpoint or something... (edit: Inserting it with the console in Chrome suggests I should be running it in IE and lists no warnings.) – Jeremy Jul 3 '12 at 2:00
  • @simchona, you should give it a try. Its a diagnostic tool. Not an malware. There are other non-Microsft tools as well (if this is the source of tension).. – vulcan raven Jul 3 '12 at 2:02
  • 5
    You just seem to be trying to sell or push things – simchona Jul 3 '12 at 2:03
  • @JeremyBanks, yes you can either save the page and inject or you can trigger the inspector manully. Are you using Firefox? You can use greasemonkey ad-on to inject in the loaded document. – vulcan raven Jul 3 '12 at 2:05
  • @simchona, my intent is to give the right people awareness about their product. Its more of a feedback and discussion. Why are you so hard to undermine any chance of productivity? – vulcan raven Jul 3 '12 at 2:09
  • 1
    @simchona "They" in this case seems to be Microsoft. I don't think OP is shilling for them... – Jeremy Jul 3 '12 at 4:28
  • 1
    @Flexo, ever heard of RIA? RIA without JS is like body without a soul. – vulcan raven Jul 27 '12 at 8:25
  • 1
    @vulcanraven twitter, facebook, slashdot, Stack Exchange, BBC all manage to do something saner than an empty page without JS. – Flexo Jul 27 '12 at 8:28
  • 1
    If you're interested, my latest blog post was inspired by this question. – balpha Jul 27 '12 at 14:29

First of all, of course browser sniffing should be avoided wherever possible. Everytime a new IE version comes out, some sites break, because suddenly a feature isn't broken anymore. The IE team has recently decided that going with standards may actually be a better idea than always inventing their own stuff. That's great. But it's also not suprising that lots of sites employ some ugly hacks to make things work in IE, because for a decade, they had to.

But just because a page checks for the existence of ActiveXObject or attachEvent does not mean that page is going to break in IE10. I wouldn't even consider this browser sniffing in all cases – quite the contrary; checking for the existence of such properties checks for the existence of a feature.

But even if they are used for browser sniffing, like in jQuery's support.xxxBubbles check (have a look at that code), this may be just used for taking a shortcut: If you use a non-IE browser, where you know that feature X works fine, there's no point in running the feature detection in the first place; if it turns out to work after all, great! But if you're running IE, you have to do the test. So guess what: You do feature detection, but hide it behind a browser sniffing check. Best of both worlds!

Second, let me give you two examples where we actually do browser sniffing, straight from our source code. The first one is from chat:

if ($.browser.msie) {
    // IE fires the onstorage event without giving the event handler
    // access to the data, neither through the event object nor by
    // updating the localStorage *before* calling the handler. Quoting
    // MSDN:
    //   "Internet Explorer fires events when data in a storage area is
    // updated, so that information can synchronized between multiple
    // instances of the browser or tabs."
    // Yeah, right.

    // However, testing (see http://chat.meta.stackoverflow.com/rooms/242)
    // shows that the data almost always is available if checked in a
    // 1-millisecond timeout created from the event handler (so probably
    // a threading issue). In any case it never seems to take more than
    // 50 milliseconds after the event fires for the data to be available.
    // Hence we try the 1-ms timeout, and if no new data was found,
    // we try again (once) after 100 ms.

    // This bug seems to have been fixed in IE9.

How are you going to feature-detect an erratically appearing concurrency bug in the communication between two windows? But the workaround employed in that if block is not an actual problem for browsers that aren't broken – it just makes the handling a bit slower. So the point of browser sniffing is skipping unnecessary workarounds in known-to-be working-browsers.

The second example is from the main site JavaScript, and note that it's not even related to IE:

// Several of the comment controls are very close to each other and to
// other links. When the Android browser thinks element A is clickable
// (because it's a link or has an onclick handler), and it thinks
// element B is not, and A is close to B, and you tap on B, the browser
// thinks you have fat fingers and pretends you tapped on A. Since event
// delegation doesn't create click handlers on the particular element,
// the Android browser doesn't know it should consider it a hit area.
// To work around this, we do the following: If the element is *touched*
// (the touchstart event sends the *correct* target element), we add a
// dummy click handler to it and add a dummy attribute. The latter
// DOM change is necessary for Android to reconsider its hit areas.
// This adds a few unnecessary click handlers on touch-enabled devices,
// but is otherwise free of side-effects. And at most one handler will be
// added per element.
function heyAndroidThisIsClickable(context, ancestor, targetSelector) {
    if (!/Android/.test(navigator.userAgent))
    // ...

Do you have a smart idea on how to do this via feature detection? Ask the user to do a touchscreen calibration on each page? And again, the user agent check is just made for a shortcut here; if it's not an Android browser, the workaround doesn't have to happen. But if it's the Android browser and it doesn't have this issue (it e.g. seems to be fixed or at least improved in the shipped browser in ICS), the workaroung doesn't cause issues either; as the comment says, it just "adds a few unnecessary click handlers".

That said, there may be cases where we make decisions based on feature detection where we shouldn't, and which should be changed at some point. But unless this actually breaks stuff, there's no reason to immediately drop everything and go fix it in a haste; certainly not just because the "Please please believe us, IE doesn't suck anymore" compat inspector for an unsupported browser version identifies something as "possible".

A small note regarding the jQuery version: As Jeremy said, we're indeed one minor version behind, but that's not even what your screenshot is talking about. It just notes that we use jQuery 1.7.1, and doesn't even complain about that.

What you're referring to is a message about jQuery UI. And we don't even use that in the first place!

Please incorporate the indicated changes all over the stackexchange ecosystem.

Thank you very much for your kind, considerate, and not at all condescending explanation of what we're doing wrong, and welcome to the real world.

  • 2
    First of, I'm not referring to jQuery-UI or anything but whats used in SO source. Remember this is supposed to be a feedback merely for 5 warnings found on SO. Like I replied to Jermy's answer, browser sniffing is carried out in SO's javascript where it can be substituted by feature detection. For example, in cdn.sstatic.net/js/full.js file, we got window.attachEvent?window.attachEvent("onmessage",d):window.addEventListener("message",d,!1); which can be replaced by window.addEventListener?window.addEventListener("message",d,!1):window.attachEvent("onmessage",d);. – vulcan raven Jul 3 '12 at 12:44
  • 11
    So we check for the presence of an API, and if that API is present, we use it. And you claim that this is not feature detection. Do you not realize how ridiculous that is? If you find actual bugs occuring in supported browsers, please report them, and we'll be very grateful and happy to fix them. If all you want to do is prove that you're smarter than the rest of us, fine. I'll grant you that. Have a great day. – balpha Jul 3 '12 at 13:32
  • 1
    How ridiculous is that you don't even agree that making decision on based of attachEvent is browser sniffing exclusively for IE? Recently prototype library is updated with these changes. Browser sniffing is not the bug neither I am calling it a bug. I gave you a real example off the SO's library. Both statements have similar effect. But the latter one (feature detection) is preferred over the first (UA detection). You are picking the scenarios which are not even present in SO code. You realize who is trying to be smarter by going out of scope? Not me. Have a good day. – vulcan raven Jul 3 '12 at 13:52
  • 3
    Happy to vote this up into "good answer" territory. – Andrew Barber Jul 3 '12 at 20:17

I'm not a Windows user, so I can't run that script myself. (I made a a Chrome user script to load it before the rest of the document, but it only displayed a recommendation that I run it in IE instead.) However, from the screenshot these all look like false alarms.

Several warnings are about the use of ActiveXObject. Using the search feature of the "Resources" tab of Chrome's developer tools, the only references I find are inside jquery.min.js. Looking at these in the unminified source, I see that jQuery is using feature detection, not browser sniffing:

if ( window.DOMParser ) { // Standard
    tmp = new DOMParser();
    xml = tmp.parseFromString( data , "text/xml" );
} else { // IE
    xml = new ActiveXObject( "Microsoft.XMLDOM" );
    xml.async = "false";
    xml.loadXML( data );
var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
xhrOnUnloadAbort = window.ActiveXObject ? function() {
    // Abort all pending requests
    for ( var key in xhrCallbacks ) {
        xhrCallbacks[ key ]( 0, 1 );
} : false,
xhrId = 0,
function createActiveXHR() {
    try {
        return new window.ActiveXObject( "Microsoft.XMLHTTP" );
    } catch( e ) {}

(Unsurprising, since Ajax handling is one of jQuery's major features.)

Similarly, attachEvent and detachEvent only show up inside jQuery and feature detection (either for the presence of attachEvent or the absence of addEventListener) is used in each case.

The only references I find to browser.userAgent are inside jQuery's browser detection. Stack Exchange uses this feature twice, but only to pick between minor CSS variations. This is more of a pain to detect that JavaScript features, and it goes wrong the consequences are insignificant.

Stack Exchange is using jQuery 1.7.1, while the latest version is 1.7.2. This is not a concern unless there is a specific issue that would be fixed.

The final issue in the screenshot is regarding drag and drop operations. As far as I know, these are not used anywhere on Stack Exchange. Also not a concern.

  • You think its "false alarm"? First of all, I tried Firefox on Ubuntu to make this Compact Inspector run via greasemonkey ad-on and it worked (no complain about IE). Secondly, after checking debug and verify for each warning and refreshing the page, the warning tells me that there is browser sniffing by attachEvent and detachEvent methods. Its being used in jQuery.min.js as well as other js from stack-exchange (sstatic.net is stack-exchange's server). – vulcan raven Jul 3 '12 at 4:07
  • @vulcanraven I missed that one, but when I search for it I still only get hits inside of jQuery. I'd be interested if they were used elsewhere, but that doesn't seem to be the case. – Jeremy Jul 3 '12 at 4:26
  • Apparently you missed the last line of my post too. sstatic.net is the stack-exchange's server. Stackoverflow and other sites call atleast 4 js files on page load. Besides google-analytics and jQuery js, 2 out of 4 files from sstatic; full.js and wmd.js are sniffing UA via attachEvent. – vulcan raven Jul 3 '12 at 4:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .