Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Javascript to check and load CSS if not loaded?

I need to check (in Javascript) if a CSS file is loaded and if not then to load it. jQuery is fine.

like image 257
foreline Avatar asked Jan 18 '11 13:01

foreline


People also ask

Can JavaScript interact with CSS?

No. CSS can not access Javascript variables.

Is CSS loaded before JS?

When it comes to ordering your CSS and JavaScript, you want your CSS to come first. The reason is that the rendering thread has all the style information it needs to render the page. If the JavaScript includes come first, the JavaScript engine has to parse it all before continuing on to the next set of resources.


2 Answers

Just check to see if a <link> element exists with the href attribute set to your CSS file's URL:

if (!$("link[href='/path/to.css']").length)     $('<link href="/path/to.css" rel="stylesheet">').appendTo("head"); 

The plain ol' JS method is simple too, using the document.styleSheets collection:

function loadCSSIfNotAlreadyLoadedForSomeReason () {     var ss = document.styleSheets;     for (var i = 0, max = ss.length; i < max; i++) {         if (ss[i].href == "/path/to.css")             return;     }     var link = document.createElement("link");     link.rel = "stylesheet";     link.href = "/path/to.css";      document.getElementsByTagName("head")[0].appendChild(link); } loadCSSIfNotAlreadyLoadedForSomeReason(); 
like image 81
Andy E Avatar answered Oct 05 '22 05:10

Andy E


I just had to write something like that and I wanted to share it. This one is prepared for multiple cases.

  • If there is no request for the css file (css file isn't linked ...)
  • If there is a request for the css file, but if it failed (css file is no longer available ...)

var styles = document.styleSheets; for (var i = 0; i < styles.length; i++) {     // checking if there is a request for template.css     if (styles[i].href.match("template")) {         console.log("(Iteration: " + i + ") Request for template.css is found.");         // checking if the request is not successful         // when it is successful .cssRules property is set to null         if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {             console.log("(Iteration: " + i + ") Request for template.css failed.");             // fallback, make your modification             // since the request failed, we don't need to iterate through other stylesheets             break;         } else {             console.log("(Iteration: " + i + ") Request for template.css is successful.");             // template.css is loaded successfully, we don't need to iterate through other stylesheets             break;         }     }     // if there isn't a request, we fallback     // but we need to fallback when the iteration is done     // because we don't want to apply the fallback each iteration     // it's not like our css file is the first css to be loaded     else if (i == styles.length-1) {         console.log("(Iteration: " + i + ") There is no request for template.css.");         // fallback, make your modification     } } 

TL;DR version

var styles = document.styleSheets; for (var i = 0; i < styles.length; i++) {     if (styles[i].href.match("css-file-name-here")) {         if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {             // request for css file failed, make modification             break;         }     } else if (i == styles.length-1) {         // there is no request for the css file, make modification     } } 

Update: Since my answer got a few upvotes and this led me to revise the code, I decided to update it.

// document.styleSheets holds the style sheets from LINK and STYLE elements for (var i = 0; i < document.styleSheets.length; i++) {      // Checking if there is a request for the css file     // We iterate the style sheets with href attribute that are created from LINK elements     // STYLE elements don't have href attribute, so we ignore them     // We also check if the href contains the css file name     if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {          console.log("There is a request for the css file.");          // Checking if the request is unsuccessful         // There is a request for the css file, but is it loaded?         // If it is, the length of styleSheets.cssRules should be greater than 0         // styleSheets.cssRules contains all of the rules in the css file         // E.g. b { color: red; } that's a rule         if (document.styleSheets[i].cssRules.length == 0) {              // There is no rule in styleSheets.cssRules, this suggests two things             // Either the browser couldn't load the css file, that the request failed             // or the css file is empty. Browser might have loaded the css file,             // but if it's empty, .cssRules will be empty. I couldn't find a way to             // detect if the request for the css file failed or if the css file is empty              console.log("Request for the css file failed.");              // There is a request for the css file, but it failed. Fallback             // We don't need to check other sheets, so we break;             break;         } else {             // If styleSheets.cssRules.length is not 0 (>0), this means              // rules from css file is loaded and the request is successful             console.log("Request for the css file is successful.");             break;         }     }     // If there isn't a request for the css file, we fallback     // But only when the iteration is done     // Because we don't want to apply the fallback at each iteration     else if (i == document.styleSheets.length - 1) {         // Fallback         console.log("There is no request for the css file.");     } } 

TL;DR

for (var i = 0; i < document.styleSheets.length; i++) {     if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {         if (document.styleSheets[i].cssRules.length == 0) {             // Fallback. There is a request for the css file, but it failed.             break;         }     } else if (i == document.styleSheets.length - 1) {         // Fallback. There is no request for the css file.     } } 
like image 34
akinuri Avatar answered Oct 05 '22 06:10

akinuri