Anmelden

Beni

As Behnam Taraghi in my ID card, student, colleague, good friend in university & at my office :-)
  • Blogs
  • Beni
  • Calling callback functions after CSS load completes

Calling callback functions after CSS load completes

  • Öffentlich
Von Beni vor 1339 Tagen

If you have already developed RIAs with the focus of javascript client side programming, you might have come across the problem to execute some lines of code (normally wrapped in a callback function) after your JS lib is loaded completely. this is solved very nice with jQuery $.getScript function and its callback parameter.

But what about CSS? If you load your new CSS dynamically and want to make some DOM manimulations or design adjustments after switching CSS according to the newly loaded CSS style, you need to call a callback function after your css is loaded completely. The solution that I applied is as follows.

Add you CSS link to the head of the document. When CSS load is finished it must be found in the DOM tree. If you can find it, grat, you can call your callback function :-) if not try it later, lets say in an interval of 5 ms. The time you see it in DOM, it is loaded completely and you can call your callback function.

Following is the JS code with jQuery:

window.lastStaticStyleSheetIndex = document.styleSheets.length-1; 
window.loadedLinks = []; // append css link to the head of the document
appendCSSLinkToHead = function(url, title) {
       
    var oLink = document.createElement("link")
    oLink.href = url;
    oLink.rel = "alternate stylesheet";
    oLink.type = "text/css";
    oLink.media = "screen";
    oLink.title = title;
    document.getElementsByTagName("head")[0].appendChild(oLink);    window.loadedLinks.push(title);
}switchCssTo = function(url, title) {
    if($.inArray(title, window.loadedLinks) == -1) {
        appendCSSLinkToHead(url, title);
    }
    var css_num = window.lastStaticStyleSheetIndex;
    $("link").filter("[title][rel*=stylesheet]").each(function(i) {
        this.disabled = true;
        this.disabled = (this.title != title);
        if(!this.disabled) css_num+=i;
    });   
    callCallBackFunc(css_num, 0);
}callCallBackFunc = function (b, t) {
   
    /* apply only if the css is completely loded in DOM */
    try {
        // FF if css not loaded an exception is fired
        if (document.styleSheets[b].cssRules) {
            callBack();
        }
        // IE no exception is fired!!!
        else {
            if (document.styleSheets[b].rules && document.styleSheets[b].rules.length) {
                callBack();
            }
            else {
                callRecursive(50, b, t);
            }
        }
    }
    catch(e) {
        //debug(e);debug('time: '+t)
        callRecursive(50, b, t);
    }
   
    function callRecursive(n, b, t) {
        // try max until n
        if(t < n) {
            // try each 5ms intervals
            setTimeout(function() {
                callCallBackFunc(b, t+5);
            }, t+5);
        }
    }
} //------------------------------------callBack = function(){   
    // your code here
}switchCssTo("path/to/newCss/newCss.css", "newCss")

I should add here it is tested only on IE8 and FF3+

I appreciate any other ideas and solutions or suggestions. Let me know if you have an idea on this issue :-)