skip to content

New Offset Method Saves Your Draggables

3 min read

After having to step away for sometime, I was able to complete the rewrite of the offset method for jQuery. As my last post on the subject mentioned, the performance of the offset method had some room for improvement. So, how does the new offset method stack up?

jQuery 1.2.6 Offset vs. The New Offset
Browser jQuery 1.2.6 New Offset
FireFox 2 225ms 45ms
FireFox 3 52ms 16ms
Safari 2 243ms 43ms
Safari 3 34ms 4ms
Opera 9.62 (mac) 22ms 10ms
Internet Explorer 6 70ms 20ms
Internet Explorer 7 40ms 20ms

The test case was simple. Two nested divs with margin, border and padding. I got the offset of the innermost div 200 times.

As you can see from these results FireFox 2 and Safari 2 had the most to gain. It just so happens those two browsers (and Safari 3) are the only ones who still have not implemented the getBoundingClientRect method.

Performance Isn’t Everything

Performance was a large reason that I decided to rewrite the offset method from the ground up, but it wasn’t the only reason. Getting the offset of an element in the various browsers has all sorts of oddities (bugs) involved. To get around them I would do all sorts of browser detection. This made the code hard to read, hard to maintain, and limited its potential.

I’m very proud to say that this new offset method no longer does any browser detection. Instead it relies on quick, simple test cases to identify certain behaviors. These test cases only run when needed and only take about one millisecond.

Be Nice, Don’t Position the Body Element

There are still, what I’d like to call, edge case issues that exist in both versions of the offset method. For example, if you position the body element or add a border to it, all bets are off. Just don’t do it. Margin and padding are safe but you probably zero them out anyways as part of your CSS reset.


I’d like to shout-out to Garrett Smith, he did an outstanding job on his version of the offset method for the APE Library.