Question

I'm trying to embed a part of html to a website via DOM manipulation. So I first load the css, then load the HTML. Here's my code;

function load_css () {
     var css_file = document.createElement("link");
     css_file.rel = "stylesheet";
     css_file.type = "text/css";
     css_file.href = "http://domain/path/to/css";
     if (css_file.readyState) {
         css_file.onreadystatechange = function () {
              if (css_file.readyState === "loaded" || css_file.readyState === "complete") {
                  css_file.onreadystatechange = null;
                  load_module();//ajax call to embed html
              }
         };
     } else {
         css_file.onload = function () {
            load_module();//ajax call to embed html
         };
     }
     document.getElementsByTagName("head")[0].appendChild(css_file);
 }

This works perfectly on IE8+, Firefox, Chrome, Opera (Linux,Mac,Windows), Safari (Mac, iPad). But it doesn't work on Safari (Windows, iPhone) and Chrome (Android).

The alternate solution is to load html without waiting for css file but I don't want users to experience synchronization problem between css file and html (unstyled html turning into styled one).

What's the best practice to make this work in Safari (Windows, iPhone) and Chrome (Android) ?

Was it helpful?

Solution

The only crossbrowser solution for this issue seems to check the document.styleSheets array to see if css has been loaded or not in an interval and set flags. So the solution is is;

var module_loaded=false;
function load_css () {
    var css_link = "domain/path/css"
    var css_file = document.createElement("link");
    css_file.rel = "stylesheet";
    css_file.type = "text/css";
    css_file.href = css_link;
    var loaded = false;
    if (css_file.readyState) {
        css_file.onreadystatechange = function () {
            if (css_file.readyState === "loaded" || css_file.readyState === "complete") {
                css_file.onreadystatechange = null;
                loaded = true;
                load_module();
            }
        };
    } else {
        css_file.onload = function () {
            loaded = true;
            load_module();
        };
    }
    document.getElementsByTagName("head")[0].appendChild(css_file);
    var ti = setInterval(function() {
        if (module_loaded) {
            loaded = true;
            clearInterval(ti);
        }
        if (!loaded) {
            for (var i = 0 ; i < document.styleSheets.length; i++) {
                if (document.styleSheets[i].href == css_link) {
                    loaded = true;
                    clearInterval(ti);
                    load_module();
                }
            }
        }
    }, 100);
}

I set module_loaded to true if load_module() function is called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top