Dojo and IE8 Compatibility

On April 18, 2014, in Javascript, Browsers, by Anuj Gakhar

As a web developer, we all have to write cross-browser code on a day to day basis and most of the time, cross-browser really means making sure the code works in different versions of IE. IE10 and IE11 are a lot better than IE9 in terms of compatibility and the biggest challenge is usually IE8 and 7. In this post, I’ll try and list some of the cross-browser tips you can use to make sure your Javascript code works in IE8 (and probably IE7 too). This post is being written keeping Dojo in mind, but I think it would be easy to port these to some other library without much effort.

String.trim()

IE only started supporting the String.trim() method from version 9 onwards. So any calls to .trim() on IE8 and below will fail.

var myString = "A string with trailing spaces   ";

myString.trim(); // will fail in IE8 and below

require(["dojo/_base/lang"], function(lang) {
  lang.trim(myString); // will work across all browsers
});

You can see the source, Dojo internally uses a fallback approach if String.prototype.trim isn’t supported.

Array.filter() / Array.forEach() and other array methods

IE started supporting these Array function from IE9 onwards. .filter(), .map(), .indexOf(), .forEach(), .lastIndexOf(), .some(), .every(), .reduce(), .reduceRight() – all these functions will not work in IE8 and below. Luckily, with Dojo, you don’t have to worry. Dojo provides and implementation of all these functions in it’s array util. Looking at the source of array.js, it does not look like Dojo is using browser’s native Array functionality. Infact, I don’t even see any checks for it in the code, but interestingly, I found this jsPerf test which compares Dojo’s array and native Arrays’ forEach() performance. Your mileage may vary based on your browser, but from what I can see on this jsPerf test, Dojo’s array implementation is doing pretty good. Anyway, you do get a cross-browser Array implementation with Dojo’s Array util.

require(["dojo/_base/array"], function(array){
  // indexOf	
  array.indexOf(arrayObject, valueToFind, fromIndex, findLast);

  // lastIndexOf
  array.lastIndexOf(arrayObject, valueToFind, fromIndex);

  // forEach
  array.forEach(arrayObject, callback, fromIndex);

  // filter
  filteredArray = array.filter(unfilteredArray, callback, thisObject);

  // map
  array.map(arrayObject, callback, thisObject);

  // some
  array.some(arrayObject, callback, thisObject);
});

It looks like Dojo 2.0 will use the native Array functions and provide a shim if they don’t exist. Quoting from their website :-

In Dojo 2.0, this module will likely be replaced with a shim to support functions on legacy browsers that don’t have these native capabilities.

Setting innerHTML of a DOM node

It’s usually OK to directly set the innerHTML of a DOM node by simply setting the .innerHTML property on it but I’ve found that it’s not very reliable in IE8 and below. It works for some DOM nodes and not for others. A similar issue (and an explanation) can be found in this SO thread. Anyways, what does seem to work reliably is setting the attribute innerHTML using Dojo.

require(["dojo/dom-attr"], function (domAttr) {
  var node = document.getElementByID('myDomNode');	
  domAttr.set(node, "innerHTML", "Contents of the div");
});

JSON

This one is not really for IE8 as IE8 does support JSON parsing natively. However, if you need to support JSON in IE7, Dojo provides you a cross-browser way to do this.

require(["dojo/json"], function(JSON){
  JSON.parse('{"hello":"world"}', true);
});

Setting element attributes

If you are declaratively creating a widget and using data-dojo-props to pass in a native property, IE8 won’t like it. So, e.g. if you were setting a class attribute on a widget, you would need to wrap it in quotes to get it working.

<div data-dojo-attach-point="my.custom.widget" 
	data-dojo-props="'class': 'myCustomClass'" />

this.own

This applies to other browsers too and is very important to avoid memory leaks in the app, but as a general practice, just make sure the following are owned in any custom widgets you write :-

  • Event handlers using on
  • Topic subscriptions
  • Custom widgets created programmatically within your widget
  • Usage of aspect.before/after/once
  • Any variables you watch

I have not listed the very basic things here that pretty much every library provides. e.g. toggling between addEventListener and attachEvent for event handlers. I’ve got a separate post for this, if someone’s interested. Also, things like querying DOM nodes where it’s not natively supported (e.g. IE8 does not support document.getElementsByClassName)

Finally, I’d like to say that, always run your code via a JSHInt/JSLint parser to verify there are no syntax errors. It can be hard to spot a minor syntax error in a file sometimes and every IDE has got JSHint plugins available.

Tagged with:  

Leave a Reply

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 445 other subscribers

© 2011 Anuj Gakhar
%d bloggers like this: