Introduction
Different browsers behave differently when it comes to JavaScript, manipulating DOM and implementing CSS. So, one has to write JavaScript with conditions based on browser, version and operating system. For CSS there is no straight forward way and some hacks needed to be applied. This becomes even more complicated when mobile devices have introduced new events like
ongesturechange
, ontouchmove
, and onorientationchange
etc. Moreover, the JavaScript becomes large and it has to be delivered irrespective of the client's system. Maintaining different codes results in redundancy and is difficult to maintain.
Using the code
If you can write conditional code (remember #if in C) and different browsers/operating systems receive different copy of code then it will solve our problem. The idea is simple, the code like following
window.attachEvent("onload", loadfn);
window.addEventListener("load", loadfn, false);
is valid JavaScript but the moment you do "<Root><![CDATA[" + jscode + "]]></Root>" this also becomes a valid XML. You can parse this XML to generate the final JavaScript based on conditions provided.
The above code in IE will finally look like this:
window.attachEvent("onload", loadfn);
The client is never aware that there are different scripts for different browsers. This can also be applied to CSS.
Tags
If - This tag has two attributes 'browser' and 'os'. If attribute value is empty or if it is not defined it is assumed to be true. This tag can be declared independent of Choose tag.
Choose - This tag can only have If tags as children and as soon as the first one is satisfied, rest are ignored. Since, there is no condition specified in last if in above example it acts as else like in if else statement.
Examples of browser attribute
browser="IE>8,FIREFOX!=3"
Valid (IE version greater than 8 OR firefox version not equal to 3.)
browser="IE"
Valid (is IE)
browser="IE>5.5,CHOME"
Valid (IE version greater than 5.5 OR firefox version not equal to 3.)
browser="!FIREFOX,!CHROME"
Valid (Not a firefox browser AND not a chrome browser.)
browser=" !SAFARI==3"
Invalid (Not browser condition cannot have version specified.
Does not make sense.)
browser="!CHROME,IE=6"
Invalid (Cannot have a not browser condition with is browser condition. Does not make sense either.)
browser="IE=7.2.1"
Invalid (Only major and minor versions supported.)
Allowed browser values
APPLE_MAIL, SAFARI, CAMINO, CFNETWORK, DOLFIN2, CHROME, DOWNLOAD, KONQUEROR, OPERA, IE, LOTUS_NOTES, THEBAT, FIREFOX, BOT, THUNDERBIRD, UNKNOWN, OUTLOOK, SEAMONKEY, MOZILLA, NETFRONT, EVOLUTION, FLOCK, EUDORA, POCOMAIL, OMNIWEB, LYNX
Examples of os attribute
os="WINDOWS"
Unlike 'browser' attribute no version support is there.
Allowed OS values
PALM, BLACKBERRY_TABLET, WINDOWS, WII, MAC_OS, BLACKBERRY, SONY_ERICSSON, GOOGLE_TV, LINUX, SYMBIAN, IOS, PSP, ROKU, MAC_OS_X, SERIES40, UNKNOWN, WEBOS, MAEMO, KINDLE, SUN_OS, ANDROID, BADA
The code
The code uses UserAgentUtils
http://user-agent-utils.java.net/
and simple xml parsing. Now the only question remains "Why should I use this when jQuery takes care of browser dependency?". I would highly recommend jQuery as
- jQuery is standard.
- Lots of plug-in support is there.
- The above code may become messy at times.
But use above code for CSS or when jQuery is not able to provide customization for your code. For example,
alert("[a][b]".split(/[\]\[]+/).length)
gives different values in IE and other browsers. IE has always been the exception.
The code additionally replaces following tokens with the appropriate values
#BROWSER#
#BROWSERGROUP#
#BROWSERVERSION#
#RENDERINGENGINE#
#BROWSERMANUFACTURER#
#OS#
#OSMANUFACTURER#
#DEVICETYPE#
#ISMOBILEDEVICE#
Deploy the servlet and open
test.html provided in the source zip in Chrome, Firefox, and IE. The above idea is so simple that even you can write you own implementation from scratch in just
two days.