Today I was made aware of an interesting issue with older Peter Blum Controls, apparently the latest changes to Internet Explorer (IE) 11 was enough to cause problems with validation controls. The issue appeared to be centered around the detection of the browser version. So what was the issue with IE? 

The following represents the user agent format for IE 10:

Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)

Well meaning developers have taken advantage of this pattern over multiple releases of IE in order to determine which features *may* be available. This. Is. A. Mistake!

IE 11 broke with years of user agent convention and started looking like this:

Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko

The important changes include:

  • The "MSIE" token has been removed.
  • The "like Gecko" token has been added (interprets it either as Gecko or WebKit).
  • The browser version has been placed in a new token ("rv").

As a result of this change JavaScript detection code, based on the following pattern, will start breaking all over the place.

//THIS IS BAD, DO NOT USE!
if( navigator.userAgent.indexOf('MSIE') != -1 )
{
//Some version of IE...
}

So what is the right way to do this?

Feature Detection

Feature detection relies on the practice of testing whether a browser supports a feature before you use it. For example EventListener was absent from IE until version 9. So you can design a relatively simply function that that detects that feature rather than the version and in the absence of the EventListener feature you can use the legacy attachEvent method.

if(window.addEventListener)
{
window.addEventListener("load", somefunction, false);
}
else if(window.attachEvent)
{
window.attachEvent("onload", somefunction);
}


With the advent of HTML5 there have been inconsistent attempts, by all the major browsers, to support the new features in advance of a definitive specification. While this is a noble endeavor, developers are left detecting which browser supports what behavior. What can work successfully is verifying if a particular property exists on a global object, for example, this code checks for Geolocation API.

function hasgeolocsupport() {
return 'geolocation' in navigator;
}

A great many developers are taking advantage of libraries like Modernizr to detect HTML5 and CSS3 features in the browser and that is a very positive thing, however, I also like to make sure I look under the hood of a given library. You may find you do not need all the bloat that comes with it just to verify a single feature.