Document Information

Last modified:
2008/06/09 13:30 by wpbasti

Compute Element Location

This document is part of the qooxdoo 0.8 development process. The preliminary information provided here may not always be up-to-date. For implementation details please refer to the source code or demobrowser examples in the SVN trunk. Comments welcome!

During the 0.8 development a backport of element location was done for qooxdoo 0.7.2, qx.bom.element.Location .

This article is based on our own, often tedious investigations made over a long time. Valuable information as well as some fixes were found in the code of YUI and the jQuery dimensions plugin. Thanks.

Often one is interested in the exact location of a DOM element inside a document. At first, it does not seem too hard to compute this information, because following the usual DOM specifications it appears to boil down to a simple calculation of the elements offsets. Well, that is theory...

Digging deeper

In fact, as (way too) often in web development, there exist a lot of incompabilities, pseudo-compatibilities and heavy bugs under across the browser implementations. Even simple properties like offsetTop or offsetLeft return different values for different client engines. This makes it almost impossible to write cross-browser code in this area.

Microsoft’s Internet Explorer offers a non-standard function called getBoundingClientRect() (MSDN Reference), which returns the fully computed location. Without a lot of custom code trying to compute this using JavaScript.

In Mozilla’s Gecko exists a method getBoxObjectFor() (XULPlanet) , which is often used similar to IE‘s getBoundingClientRect(). However, this method unintentionelly lurks on ''nsIDOMNSDocument''. It contains a lot of stuff which is not useful for HTML documents and the developers recommend not to use this rather internal, not-public-API method.

Unfortunately, there is no standardized method to compute the position of a DOM element. This leads to more or less complete implementations in JavaScript libraries, which try to hide the various browser issues underneath a common interface for the web developer.

Known engine bugs

  • Mozilla and IE do not take the parent’s element borders into account
  • Mozilla does not include the border of the body, if an element isn’t positioned absolute and is without an absolute positioned parent
  • IE does not include the border of the body, if an element is positioned static and without an absolute or relative parent
  • Mozilla does not add the border of a parent that has overflow set to anything but visible
  • Safari and Opera include border on positioned parents
  • Safari and IE in Standards Mode don’t add the body margin for elments positioned static or relative
  • Mozilla does not include the border of the body, if an element isn’t positioned absolute and is without an absolute parent
  • Opera has a bad scroll value for all TR elements
  • IE inserts the (2,2) offset in standards mode, not quirks mode. It’s easy to work around: it sets document.documentElement.clientLeft and document.documentElement.clientTop to 2 in standards mode, or 0 in quirks mode.
  • CSSOM (CSS Object Model) project want to standardize getBoundingClientRect.
  • Further Mozilla bugs: 328881, 330619

Framework implementations

  • YUI (as of 2.2.2) has an implementation which seems to work quite well
  • jQuery (as of 1.1.3) has a method offset(), which has a lot of workarounds for commonly known bugs of Mozilla, Opera and Safari.
  • ExtJS (as of 1.0.1) uses an implementation based on YUI’s original code including fixes for Safari and Firefox. (Bug report in Forum
  • Dojo’s method (as of 0.9 beta) seems to be work in progress (following the code comments)
  • Mochikit has a method cumulativeOffset(), which provides an offset calculation for all browsers, but without any fixes and workarounds.
  • Mootools has a method getPosition() (Element.Dimension) which is comparable to Mochikit’s version.
  • Tibco contains an implementation respecting simple browser differences, but does not seem to contain support for Opera or Safari.
  • GWT uses getBoxObjectFor() for newer geckos and an offset calculation for older ones. (bug report 634) (See also matching gecko change Bug 330619)
  • Prototype, Scriptaclous, Base2 do not include an implementation for element position

How to solve the issue

  • Do not use getBoxObjectFor() for gecko-based clients
  • Use of getBoundingClientRect() which works quite well in IE and Gecko 1.9, and has less bugs than the offset calculation in these browsers.

An early preview can be seen in the current trunk. This works well for:

  • Gecko 1.8 + Gecko 1.9 (Firefox 2.x and Firefox 3.x alpha)
  • Internet Explorer 6 + 7
  • Safari 3.0 beta
  • Opera 9.2

Demos

There are comprehensive examples available in the demobrowser. Remember that this is the devel (not the latest stable) version, so the other examples or the demobrowser application may not always work as expected.

  • Open the demo browser with the first location example
  • Try the other location samples as well by double-clicking Location_1_std, Location_2 and Location_2_std
  • You can open each example in a separate window clicking the “yellow arrow” button in the toolbar

Information

Last modified:
2008/06/09 13:30 by wpbasti

Account

Not logged in

 
 

Job Offers

To further improve qooxdoo we are seeking javascript developers. Read more...

Rich Ajax Platform (RAP)

RAP uses qooxdoo, Java and the Eclipse development model to build rich web applications. Read more...

qooxdoo Web Toolkit (QWT)

Similar to GWT this framework allows to create impressive qooxdoo applications just using Java. Read more...

Pustefix

Pustefix is a MVC-based web application framework using Java and XML/XSLT. Read more...

 
SourceForge.net Logo

Bad Behavior has blocked 0 potential spam attempts in the last 7 days.