parentNode.org

The building blocks of a solid frontend.

Using logic to minimize cross browser scripts

Posted in JavaScript by Munter on the February 1st, 2006

Javascripters often find themselves trapped between different implementations of the same standard. In the last millennium browser detection scripts where the big thing. Since then we have luckily progressed a bit in turns of crossbrowser compatibility. Not so much because of increased compatibility, but rather because of some nifty tricks in javascript that allow us not to worry about browsers.

Compatibility detection - Objects are key

Browser detection scripts for crossbrowser compatibility are usefull, but mostly for detailed statistics, not for crossbrowser compatibility. Peter-Paul Koch explains why Object detection is far superior to browserdetection at Quirksmode.org.

The point of object detection versus browser detection is that you check for the object or method you want to use, and use that as a criterion for execution, instead of detecting the browser and then executing what you know is available in that browser. Object detection is both more simple, and much more secure, since browsers can spoof their identity and thus could make your script fail. Also you wouldn’t have to maintain a complete list of all versions of all browsers to the end of your days, which is always a bonus.

So now we know object detection is the way to go. Here is an example of a script getting the mouse coordinates from an event:

function doSomething(e) {
	var posx = 0;
	var posy = 0;
	if (!e) var e = window.event;
	if (e.pageX || e.pageY)
	{
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY)
	{
		posx = e.clientX + document.body.scrollLeft;
		posy = e.clientY + document.body.scrollTop;
	}
	// posx and posy contain the mouse
	// position relative to the document.
	// Do something with this information
}

Example taken from Event properties at Quirksmode.org.

The above example has two main object detections. Internet Explorer doesn’t use the W3C recommended DOM event handling. It uses the Microsoft proprietary window.event. So in the example, the event e is passed as an argument to the function. IE doesn’t recognise this, so it executes line 4 because if (!e) evaluates as true for IE. This sets e to window.event for Internet Explorer only.

The next two checks in the above example are similar. e.pageX and e.pageY are W3C recommended DOM event properties, and window.event.clientX/Y are MS implementations.

How boolean logic works

Let us take a look at an interesting feature in javascript boolean logic. In specific we are going to take a look at the logical OR operator: ||.

On page 58 of the ECMAScript Language Specification (730kb PDF), the implementation of the logical OR operator is described. The following sequence that explains the order of evaluation is interesting: (edited for legibility)

The production LogicalORExpression: foo || bar is evaluated as follows:

  1. Evaluate foo.
  2. Call GetValue(Result(1)).
  3. Call ToBoolean(Result(2)).
  4. If Result(3) is true, return Result(2).
  5. Evaluate bar.
  6. Call GetValue(Result(5)).
  7. Return Result(6).

Result(X) means the result of step number X

The thing to note about this implementation, is that the logical OR operator doesn’t return a boolean true/false value, but rather the value of the first expression that evaluates as true.

We also know that javascript is very loosely typed, so all the following evaluates as false:

  • false
  • null
  • undefined
  • unknown
  • (int) 0
  • (Empty string) ”

Using logic for optimization

We can use the fact that undefined is evaluated as a false statement in javascript to our advantage in javascript. Let us remember the mouse coordinate script from the first example. Here is a rewritten example with all the above knowledge applied:

function doSomething(e) {
	var e = e || window.event;
	var posx = e.pageX || e.clientX + document.body.scrollLeft || 0;
	var posy = e.pageY || e.clientY + document.body.scrollTop || 0;
}

In the above example the logical OR operator is used to return the value of the first element that evaluates as true. Imagine that we are executing the script using Internet Explorer.

The variable e is set to the value of e in case e exists. But it doesn’t, so in that case e is set to the value of window.event. Similarly we are using the alternative way to get the X and Y coordinates because IE doesn’t support e.pageX/Y.

The above code is a lot cleaner than a load of if/else constructs, and the logical OR row can be extended as long as you like. So next time you want to do crossbrowser compatible javascripts, remember the object detection using logical OR. It will make your code much more readable.

7 Responses to 'Using logic to minimize cross browser scripts'

Subscribe to comments with RSS or TrackBack to 'Using logic to minimize cross browser scripts'.


  1. on February 2nd, 2006 at 1:29 pm

    Nice writeup!

    Had no idea boolean logic could be such an effective tool in this context, I noticed you mentioned it on IRC the other day, but didn’t quite catch the idea.

    Thanks :-)

  2. Krijn said,

    on February 4th, 2006 at 6:13 pm

    This technique can also be used for default function arguments, but then you have to watch out for 0, which indeed also evaluates as false.

  3. Chris said,

    on February 6th, 2006 at 7:06 pm

    Krijn,
    Thats atually exatley what Munter is doing in the line:
    var e = e || window.event;


  4. on February 7th, 2006 at 7:04 pm

    Yeah, emphasis should be put on the last part of my comment ;)

  5. henrah said,

    on May 26th, 2006 at 4:01 am

    >all the following evaluates as false:
    > …
    > (Empty array) []

    Actually, an empty array evaluates to true.

  6. Chris said,

    on June 3rd, 2006 at 2:36 pm

    “Actually, an empty array evaluates to true.”
    Your absolutely right, article adjusted


  7. on June 19th, 2006 at 4:55 pm

    Nice article, and since I never accually took the time to read the maunal I learned something new today! I will definately use this new knowledge to improve my scripting!

Leave a Reply