I need to check (in Javascript) if a CSS file is loaded and if not then to load it. jQuery is fine.
No. CSS can not access Javascript variables.
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.
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();
I just had to write something like that and I wanted to share it. This one is prepared for multiple cases.
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. } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With