jQuery.waitFor plugin

Tuesday, 2 April 2013

Sometimes jQuery(document).ready() isn’t fast enough. It doesn’t do anything until the entire DOM has loaded. But sometimes you want your code to run against your DOM elements immediately rather than waiting until the rest of the page DOM is done. You can do this with jQuery.waitFor, a new plugin.

Usage

waitFor uses jQuery’s Deferred API, so its usage is clean and consistent with the rest of jQuery’s event-handling functions. To use it, call jQuery.waitFor() with a selector, and then call done(function() {...}) on the result. As soon as an element appears in the DOM that matches the given selector, your function will be called, with a jQuery object containing the matched element (or elements) as the argument. If the DOM already contains matching elements, the function will be called immediately.

You can also call fail(function() {...}) on waitFor‘s return value to trigger a callback if the element has not appeared by the time the full DOM is loaded.

Example

$.waitFor("header")
    .done(function(elements) { elements.addClass("fancy"); })
    .fail(function() { $("body").append("<p>Huh?</p>"); })

This will add the class “fancy” to the HTML5 header element as soon as it is loaded. If it hasn’t appeared by the time the document is ready, it adds a new element to the end of the document instead.

Download

Download waitFor from the jQuery plugin page.

You can also fork waitFor at Github. Please test it and send me your pull requests.

Usage notes

The function works by polling the DOM at short intervals. By default it polls every 23 milliseconds, but you can change this by setting $.waitFor.defaultIntervalMs before calling $.waitFor(). Alternatively you can pass something like {intervalMs: 100} as the third argument the first time you call $.waitFor(). But don’t bother changing this unless you really know what you’re doing.

waitFor returns a jQuery Promise object, so apart from done() and fail(), you can also call other methods on it like always() and then(). See the documentation for full details.

In order for waitFor to be useful, you will probably want to include the plugin code in your document head. Therefore you will also need to include jQuery in the head.

waitFor works by polling the DOM to see if anything matches the selector. Therefore if the selector is particularly slow to evaluate, there may be performance problems. So don’t do that!

History

More than 5 years ago(!) I wrote a plugin called elementReady that does the same thing as waitFor. It worked well but had some restrictions (for performance) and its usage syntax was not beautiful. After jQuery’s Deferred API came out, I tinkered with rewriting elementReady to use it, since it seemed a natural fit. As part of this, I renamed it so code using it would read better: $.waitFor(something).done(callback). And finally, last month I realised that the jQuery folks had upgraded their plugin site, so I thought I would finally release waitFor to the world.

Tags: , ,

One comment

You can leave a comment, or trackback from your own site.

Leave a comment