Best Practice: the OmegaJunior way to detecting he version of Microsoft's flagship web browser.
Used zjrJS Version:
Stable Minified version 20141202t2322 of zjrJS.
Challenges
Requirements
Some experience in HTML.
Benefits
Your web pages rise to all of the above challenges.
Dependencies
None. The example below uses zjrJS, but that is not required.
Example
The trick is not to sniff at all. Instead, we promote Microsoft's "Conditional Comments". It's a clean, native way for its browsers to execute things that other browsers will skip. Because conditional comments are written like normal HTML comments, HTML parsers will generally skip their contents. Microsoft trained its browsers to react to the condition inside the square brackets. This allows us to target browser versions.
We do not read the version out of the useragent string, for we know this can be changed rather trivially by the visitors. Instead, we use the conditional comments to let the browser decide which javascript to run, and thus, which version to set.
Notice that the example is stacking source upon source, augmenting and overruling previous sources. We found this helpful in some cases. Elsewhere, we separated instead. Which method you choose depends on the rest of your implementation.
As the above example suggests, you can add whatever source or script you require to target that specific version of the browser. We used javascript to store the version number into a variable of our choosing, and zjrJS to act upon it. That fact is unrelated to the version targeting method itself.
Notice the lack of error handling inside the conditional comments script. Please do add error handling to your scripts.
Also notice the lack of javascript / html comment tags inside the conditional comments script. That's on purpose: first of all we use CDATA tags in multiline comment tags (because that works in CSS too), but more importantly, if you end an html comment tag inside the conditional comment, you are short-circuiting the conditional comment, corrupting the remainder of your page. Let's avoid that.
Real-world implementations
This method was used by us in one client's intranet solution, which heavily depended on HTML5 and CSS3. For MSIE versions that did not understand CSS3 gradients and shadows, we substituted Microsoft DXImageTransform filters. For anything older than version 9, we performed a zjrJS.MSIE.h5A(). And for versions older than 7, we performed a 24-bit PNG alpha-transparancy substitution.
We've also used this in Zjramble5, to provide specific hints to those using MSIE versions older than 10, which at the moment of this writing is still in preview status.
We're also using this in the templates for various parts of the OmegaJunior Consultancy web site itself, including this zjrJS documentation, to urge people stuck with MSIE 6 or older, to either update or switch vendors. And yes, we try to do that in a friendly manner.
Final thought
We avoid making assumptions about what a browser can and cannot do. We deem sniffing browser version to that end rather silly. We advise using feature detection instead, and up to the moment of this writing have been able to use that method exclusively for making zjrJS cross browsers. However, when a browser's code base is unlikely to change, as is the case with older ones, we see little harm in relying on employing tried and tested exceptions.
- You or your client have decided, for some inexplicable reason, to continue support for outdated, deprecated versions of the world's most notorious web browser.
- Your web application now needs a failsafe way to detect what useragent version the visitor is using, without annoying visitors using competing brand browsers, like Firefox, Safari, Chrome, or Opera.
- Not only do you need to separate javascript between browser brands and versions, you also need to split up other sources like css.
- Your web pages needs to do this independently of the web server and server-side middleware.
- You know that visitors can change whatever browser claims to be by editing its useragent property, so your method needs to circumvent useragent spoofing.
Requirements
Some experience in HTML.
Benefits
Your web pages rise to all of the above challenges.
Dependencies
None. The example below uses zjrJS, but that is not required.
Example
<script type="text/javascript" src="zjrJS.version.js" id="zjrJS"></script>
<script type="text/javascript">/* <![CDATA[ */
var my=({
init: function(){
if("version" in my.MSIE){
alert("You seem to be using Internet Explorer " + my.MSIE.version + " to visit this page.");
}
},
MSIE:({})
})
zjrJS.Doc.aE(window, "load", my.init);
/* ]]> */</script>
<link rel="stylesheet" type="text/css" href="main.css" />
<!--[if lt IE 8]>
<script type="text/javascript">my.MSIE.version = 7</script>
<link rel="stylesheet" type="text/css" href="msie7.css" />
<![endif]-->
<!--[if lt IE 7]>
<script type="text/javascript">my.MSIE.version = 6</script>
<link rel="stylesheet" type="text/css" href="msie6.css" />
<![endif]-->
<!--[if lt IE 6]>
<script type="text/javascript">my.MSIE.version = 5</script>
<link rel="stylesheet" type="text/css" href="msie5.css" />
<![endif]-->
The trick is not to sniff at all. Instead, we promote Microsoft's "Conditional Comments". It's a clean, native way for its browsers to execute things that other browsers will skip. Because conditional comments are written like normal HTML comments, HTML parsers will generally skip their contents. Microsoft trained its browsers to react to the condition inside the square brackets. This allows us to target browser versions.
We do not read the version out of the useragent string, for we know this can be changed rather trivially by the visitors. Instead, we use the conditional comments to let the browser decide which javascript to run, and thus, which version to set.
Notice that the example is stacking source upon source, augmenting and overruling previous sources. We found this helpful in some cases. Elsewhere, we separated instead. Which method you choose depends on the rest of your implementation.
As the above example suggests, you can add whatever source or script you require to target that specific version of the browser. We used javascript to store the version number into a variable of our choosing, and zjrJS to act upon it. That fact is unrelated to the version targeting method itself.
Notice the lack of error handling inside the conditional comments script. Please do add error handling to your scripts.
Also notice the lack of javascript / html comment tags inside the conditional comments script. That's on purpose: first of all we use CDATA tags in multiline comment tags (because that works in CSS too), but more importantly, if you end an html comment tag inside the conditional comment, you are short-circuiting the conditional comment, corrupting the remainder of your page. Let's avoid that.
Real-world implementations
This method was used by us in one client's intranet solution, which heavily depended on HTML5 and CSS3. For MSIE versions that did not understand CSS3 gradients and shadows, we substituted Microsoft DXImageTransform filters. For anything older than version 9, we performed a zjrJS.MSIE.h5A(). And for versions older than 7, we performed a 24-bit PNG alpha-transparancy substitution.
We've also used this in Zjramble5, to provide specific hints to those using MSIE versions older than 10, which at the moment of this writing is still in preview status.
We're also using this in the templates for various parts of the OmegaJunior Consultancy web site itself, including this zjrJS documentation, to urge people stuck with MSIE 6 or older, to either update or switch vendors. And yes, we try to do that in a friendly manner.
Final thought
We avoid making assumptions about what a browser can and cannot do. We deem sniffing browser version to that end rather silly. We advise using feature detection instead, and up to the moment of this writing have been able to use that method exclusively for making zjrJS cross browsers. However, when a browser's code base is unlikely to change, as is the case with older ones, we see little harm in relying on employing tried and tested exceptions.