i\'m trying to attach an event handler to the load event of a link tag, to execute some code after a stylesheet has loaded.
new_element = document.createElem
An href does not have a load event you need to apply your stuff as the page itself loads e.g.
window.onload = function(){
//code here
}
use the function on this page: http://www.dustindiaz.com/top-ten-javascript/
to add the event the body element (in line would be )
E.g. Android browser doesn't support "onload" / "onreadystatechange" events for element: http://pieisgood.org/test/script-link-events/
But it returns:
"onload" in link === true
So, my solution is to detect Android browser from userAgent and then wait for some special css rule in your stylesheet (e.g., reset for "body" margins).
If it's not Android browser and it supports "onload" event- we will use it:
var userAgent = navigator.userAgent,
iChromeBrowser = /CriOS|Chrome/.test(userAgent),
isAndroidBrowser = /Mozilla\/5.0/.test(userAgent) && /Android/.test(userAgent) && /AppleWebKit/.test(userAgent) && !iChromeBrowser;
addCssLink('PATH/NAME.css', function(){
console.log('css is loaded');
});
function addCssLink(href, onload) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", href);
document.head.appendChild(css);
if (onload) {
if (isAndroidBrowser || !("onload" in css)) {
waitForCss({
success: onload
});
} else {
css.onload = onload;
}
}
}
// We will check for css reset for "body" element- if success-> than css is loaded
function waitForCss(params) {
var maxWaitTime = 1000,
stepTime = 50,
alreadyWaitedTime = 0;
function nextStep() {
var startTime = +new Date(),
endTime;
setTimeout(function () {
endTime = +new Date();
alreadyWaitedTime += (endTime - startTime);
if (alreadyWaitedTime >= maxWaitTime) {
params.fail && params.fail();
} else {
// check for style- if no- revoke timer
if (window.getComputedStyle(document.body).marginTop === '0px') {
params.success();
} else {
nextStep();
}
}
}, stepTime);
}
nextStep();
}
Demo: http://codepen.io/malyw/pen/AuCtH
All credit goes to Tobiasz up above, but here's a little expansion on what he said:
function _cssIsLoaded(cssStylesheet) {
var cssLoaded = 0;
try {
if ( cssStylesheet.sheet && cssStylesheet.sheet.cssRules.length > 0 )
cssLoaded = 1;
else if ( cssStylesheet.styleSheet && cssStylesheet.styleSheet.cssText.length > 0 )
cssLoaded = 1;
else if ( cssStylesheet.innerHTML && cssStylesheet.innerHTML.length > 0 )
cssLoaded = 1;
}
catch(ex){ }
if(cssLoaded) {
// your css is loaded! Do work!
// I'd recommend having listeners subscribe to cssLoaded event,
// and then here you can emit the event (ie. EventManager.emit('cssLoaded');
} else {
// I'm using underscore library, but setTimeout would work too
// You basically just need to call the function again in say, 50 ms
_.delay(_.bind(this._cssIsLoaded, this), 50, cssStylesheet);
}
}
You'd call it with something like (using jquery):
var link = $("<link>");
link.attr({
type: 'text/css',
rel: 'stylesheet',
href: sheet
});
$("head").append(link);
// link.get(0), because you want the actual element, not jQuery-wrapped element
self._cssIsLoaded(link.get(0));