The YUI Get Utility makes it easy to dynamically load CSS and JavaScript on demand, but there’s one tiny gotcha: Firefox, Safari, and other Gecko/WebKit-based browsers don’t provide a reliable way to tell when a CSS file has finished loading. As a result, when you load CSS in one of these browsers using the Get.css() method, the onSuccess callback is fired instantly.
In many cases this isn’t a problem, but if you need to ensure that you don’t perform an action (such as appending HTML to the page) until after the CSS has loaded, this can cause a race condition. There’s no way for the Get Utility to automatically work around this problem, but with a little bit of extra effort on our part, we can work around it ourselves.
The trick is to include a rule at the end of the dynamically-loaded CSS file that will send a message to our script by setting a style property on a special element. Once we see that property change, we know the CSS has finished loading.
First, the contents of our CSS file:
/* ... imagine lots of other CSS here ... */
#css-done { display: none; }
And now the JavaScript that will load it:
(function () {
var Y = YAHOO;
Y.util.Get.css('example.css', {
onSuccess: function () {
var el, poll;
function finished() {
alert('CSS has finished loading.');
}
if (Y.env.ua.gecko || Y.env.ua.webkit) {
el = document.body.appendChild(document.createElement('div'));
el.id = 'css-done';
poll = function () {
if (Y.util.Dom.getStyle(el, 'display') === 'none') {
// Once the element's display property changes, we know the CSS has
// finished loading.
el.parentNode.removeChild(el);
finished();
} else {
// The element's display property hasn't changed yet, so call this
// function again in 50ms.
setTimeout(poll, 50);
}
};
poll();
} else {
finished();
}
}
});
})();
Comments
Great idea, hopefully a solution can be baked in
Ryan,
Nice example of a way to fix an issue with the Get Utility. Although it’s very specific as it requires a certain CSS selector with declarations to be present in your CSS files; I think it’s a great way to resolve any issues which might come up for someone using dynamic loading.
Very informative
Very informative article. Thanks