michael.futreal.com > jQuery > ready vs. onload

Images, $(document).ready(), and onload

The Problem with Underspecified <img> Elements

Firefox 2.0, at least, meets the conditions necessary to trigger jQuery's $(document).ready() before it finishes loading images. This is not a bug — the DOM is essentially complete prior to images being fully downloaded — but Firefox's convention can nevertheless pose problems if your .ready() code needs to utilize the size of some still-to-be-loaded image.

Normally, well-specified XHTML sidesteps this problem by supplying all necessary attributes needed for rendering. In other words, the typical and best case thing to do is to directly specify the height and width attributes for an image. However, if you find yourself in a scenario where this is not practical for some reason (working with wiki-generated content, for instance), then any presentational .ready() code contingent upon image dimensions may produce erroneous results. DOH!

I discovered this effect playing around with my jQuery plugin, vjustify. Because that plugin is designed to fix CSS column shortcomings, you would almost always want to run it in a .ready() context.

Examples: Varying Results for Images

The following examples attempt to report the height of <img> element that lacks a specified height attribute. Both example pages utilize jquery-1.0.3.

The $(document).ready() example may fail in Firefox 2.0.

The runOnLoad example will likely succeed in Firefox 2.0.

Conclusion: the Work-Around

If you are faced with a situation where a) you can't be sure that <img> tags will be properly specified or styled at fixed sizes and b) you need to run code that takes <img> dimensions into account, then you'll probably need to eschew the elegant jQuery deferral mechanism in favor of another solution like runOnLoad.

Note that runOnLoad can happily coexist with jQuery, so you can keep doing everything else the jQuery way. At some point, someone, if not me, will get around to writing a plugin version of the runOnLoad way of deferring code.