Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Cross Browser JavaScript

0.00/5 (No votes)
15 Dec 2005 1  
A not widely known trick to make your programming easier by implementing a small compatibility layer, when programming for multiple browsers.

Introduction

If you have to implement a Web application that intensively uses JavaScript for some client side effects or some AJAX like features, and if you have to support more than Microsoft Internet Explorer 6.0, then you might find here a not widely known trick to make your programming easier by implementing a small compatibility layer.

Both browsers, Microsoft Internet Explorer and Mozilla/FireFox, do have a lot of functionalities as defined by the standards HTML, CSS and JavaScript, and some of them are really useful for implementing some functionality on the client. Because there are some extensibility features available on these different platforms, it is possible to extend one browser with methods and properties that are not available in the other one out of the box.

JavaScript Prototypes

The JavaScript language interpreters included in the browser platforms offer almost identical functionalities. There is no real need to use this feature to bring some missing functionalities to one of the platforms, but it is an interesting feature anyway and it gives you the chance of extending both platforms.

The object types of JavaScript, better called intrinsic objects of JavaScript (String, Number, Array, �) that are part of the JavaScript language have an extensibility mechanism by using the available prototype property.

By attaching new functions to the prototype, you make this method available to all objects that derive from that type.

The following sample adds a trim() method to all string objects that eliminates all leading and trailing blanks and returns a new string with the remaining characters (if any):

String.prototype.trim =      function() {
  return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
}

To use this function, you will use the following syntax:

var s = "    Hello World      ";
var txt = s.trim(); // returns only "Hello World"

You can use this extensibility feature in Internet Explorer and Mozilla/FireFox to add new methods and (readonly) properties to the intrinsic objects, but there is no cross browser way to capture the access to properties of those objects.

You might think that it is also possible to add a global method trim(s) that uses a parameter and the return value to do the same thing, but you might get in conflict with other variables or methods from different libraries using the same name. You can also add a trim method to the Array object that handles array items, without getting a conflict.

Some general information about the prototype property can be found at: MSDN.

JavaScript Prototypes in Mozilla/FireFox

The Mozilla/FireFox platform also offers a proprietary but very useful extension model that allows to also implement properties on the JavaScript intrinsic objects. Here I added a weight property that returns the sum of the char codes of a string:

String.prototype.__defineGetter__("weight", 
  function () {
    var w = 0;
    for (var n = 0; n < this.length; n++)
      w += this.charCodeAt(n);
    return w;
  }
);

You can use this property on any string:

var s = "ABC";
var n = s.weight; // will return 198

Remember:

The __defineGetter__ and __defineSetter__ are unique features to Mozilla/FireFox and you can find some (still few) samples on the internet by searching through Google for these keywords.

Prototypes with HTML objects

JavaScript objects and HTML objects are completely different kinds of objects when using the Microsoft Internet Explorer but with Mozilla/FireFox, these objects share a common implementation. So, the feature we look at now is only available in Mozilla/FireFox.

The Internet Explorer, for example, supports a innerText property on many HTML objects like span, div, p, � that can be used to safely access and set the text of an HTML object.

Mozilla/Firefox, in contrary, uses the textContent property that is part of the newer DOM Level 3 standard to do the same thing.

Now you can use the extensibility features of Mozilla/FireFox to emulate an innerText property on all HTML objects and you can eliminate all conditional scripting across your JavaScript programs:

var isIE = (window.navigator.userAgent.indexOf("MSIE") > 0);

if (! isIE) {
  HTMLElement.prototype.__defineGetter__("innerText", 
              function () { return(this.textContent); });
  HTMLElement.prototype.__defineSetter__("innerText", 
              function (txt) { this.textContent = txt; });
}

You just have to include this script in one of your common JavaScript include files.

Here are some more usable wrappers to Microsoft specific features:

innerText Gets and Sets the inner text of HTML nodes.
obj.children[] Returns the obj.childNodes[] collection. This is not a perfect emulation but probably helps making your code work.
XMLDocument Returns a XMLDocument object from the inner text that should be XML.
attachEvent Attach event handlers to HTML objects.
detachEvent Detach event handlers from HTML objects.
window.event Return the actual executing event object.
event.srcElement Return the target node of the executing event.
event.cancelBubble Stop the propagation of the current event.
event.returnValue Set the return value of the current event.
xmlobj.selectSingleNode Return a single node from an XML element by using an XPath expression.
xmlobj.text Return the inner text of an XML element.

Conclusion

If you ever thought that writing cross browser compatible JavaScript is hard to do, you now have a chance to build your layer of compatibility and make your script more readable and easier to maintain, and get rid of the conditional code fragments spread all over your web application.

This approach helps a lot but is not the definitive solution. A lot of people (including myself) hope that the current and upcoming standards will get implemented in all browsers. It's better to use these features, when available on multiple platforms. There are also good samples of proprietary Microsoft Internet Explorer features that are so useful that Mozilla/Firefox did implement them. The most popular sample to this is the XMLHTTP object that allows AJAX like cross browser implementations.

Some good reading URLs for browser compatibility hints:

When implementing AJAX enabled frameworks, JavaScript coding gets more important. There are not many JavaScript libraries that already use this kind of an approach but some newer ones do. Here some links:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here