Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing load event on LINK

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.createElement('link');
new_element.type = 'text/css';
new_element.rel = 'stylesheet';
new_element.href = 'http://domain.tld/file.css';
new_element.addEventListener('load', function() { alert('foo'); }, false);
document.getElementsByTagName('head')[0].appendChild(new_element)

I have tried onreadystatechange as well:

new_element.onreadystatechange = function() { alert('foo'); }

Unfortunately neither approach results in an alert being triggered. Furthermore, new_element.onload is null after registering a handler for the load event with addEventListener. Is that normal?

PS: I may not use any framework in solving this.

like image 458
pgn Avatar asked Apr 14 '10 08:04

pgn


2 Answers

Here's what is, in my opinion, a better solution for this issue that uses the IMG tag and its onerror event. This method will do the job without looping, doing contorted style observance, or loading files in iframes, etc. This solution fires correctly when the file is loads, and right away if the file is already cached (which is ironically better than how most DOM load events handle cached assets). Here's a post on my blog that explains the method - Back Alley Coder post - I just got tired of this not having a legit solution, enjoy!

var loadCSS = function(url, callback){
    var link = document.createElement('link');
        link.type = 'text/css';
        link.rel = 'stylesheet';
        link.href = url;

    document.getElementsByTagName('head')[0].appendChild(link);

    var img = document.createElement('img');
        img.onerror = function(){
            if(callback) callback(link);
        }
        img.src = url;
}
like image 172
csuwldcat Avatar answered Oct 08 '22 23:10

csuwldcat


For CSS stylesheets (not LINK elements in general) i'm using manual interval, by poking it's rules length. It works crossbrowser (AFAIT).

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){}

In code above, the cssStylesheet is DOMElement.

like image 42
Tobias Cudnik Avatar answered Oct 08 '22 21:10

Tobias Cudnik