How to Use JavaScript to Check and Load CSS If Not Loaded

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

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();

Check css file loaded or not using document.styleSheets

I tried your code ant it works for me, ( on chrome, with internal css ), but it fails when using external css loaded from CDN's, so i would guess your problem is "rules" property as mentioned by @PatrickEvans.

If you don't find any other good way, then you may add an element to the page that doesn't affect the page display, but can be checked for a change.

e.g add a specific css rule like this.

html body div#my_stylesheet_name {
width: 112px !important;//random width that is unlikely overwritten by another css
}
<div id="my_stylesheet_name" style="height:0; width: 0;display: none;"></div>

//then use javascript timer/interval to check if
element with id of "my_stylesheet_name" has width of 112, if so, then it means css has loaded.

Edit - If you dont have any other option, you may consider something like this ( i havent used it myself before so test browser compatibility before using it )

1) create the element using JS

2) add on error and onload events, and use those to do your magic

    var link;
link = document.createElement("link");
link.setAttribute("type", "text/css");
link.onload=function( evt ) {
console.log("LINK LOADED", evt );
};
link.onerror=function( evt ) {
console.log("LINK Error", evt );
};
link.setAttribute("rel", "stylesheet");
link.setAttribute("href", "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css");
document.getElementsByTagName("head")[0].appendChild(link);

Load CSS file only if element with class is present on the page

Create the nodes first then append then using the appendChild() method, like :

var scriptNode = document.createElement("script");
scriptNode.src = "/wp-content/themes/gowebsites/gw-addon/js/wow.js";

var cssNode = document.createElement("link");
cssNode.href = "/wp-content/themes/gowebsites/gw-addon/css/animations.css";
cssNode.rel = "stylesheet";

head.appendChild(scriptNode);
head.appendChild(cssNode);

How to load up CSS files using Javascript?

Here's the "old school" way of doing it, which hopefully works across all browsers. In theory, you would use setAttribute unfortunately IE6 doesn't support it consistently.

var cssId = 'myCss';  // you could encode the css path itself to generate id..
if (!document.getElementById(cssId))
{
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.id = cssId;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'http://website.example/css/stylesheet.css';
link.media = 'all';
head.appendChild(link);
}

This example checks if the CSS was already added so it adds it only once.

Put that code into a JavaScript file, have the end-user simply include the JavaScript, and make sure the CSS path is absolute so it is loaded from your servers.

VanillaJS

Here is an example that uses plain JavaScript to inject a CSS link into the head element based on the filename portion of the URL:

<script type="text/javascript">
var file = location.pathname.split( "/" ).pop();

var link = document.createElement( "link" );
link.href = file.substr( 0, file.lastIndexOf( "." ) ) + ".css";
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";

document.getElementsByTagName( "head" )[0].appendChild( link );
</script>

Insert the code just before the closing head tag and the CSS will be loaded before the page is rendered. Using an external JavaScript (.js) file will cause a Flash of unstyled content (FOUC) to appear.

Detect js/css file loading failure

You can load your scripts in javascript.
For example:

var scriptsarray=new Array(
"script1.js",
"script2.js",
"style1.css",
"style2.css"
)

var totalloads=0;

for (var i=0;i<scriptsarray.length;i++){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptsarray[i] + '?rnd=' + Math.random();
document.body.appendChild(script);
script.addEventListener('load', wholoads, false);
script.addEventListener('error', errload,false);
}

function wholoads(scriptname){
totalloads++;
if (totalloads==scriptsarray.length){alert('All scripts and css load');}
}

function errload(event){

console.log(event);
}

Is there any way to detect when a CSS file has been fully loaded?

edit: It should be noted that browser support for onload events on CSS files has improved since my original answer. It is not fully supported though, so my answer below still has some relevance. Here is a compatibility chart, not sure how legit the source is though.

Ok, I finally found a solution.

This guy http://tugll.tugraz.at/96784/weblog/9080.html inserts link-tags and polls document.styleSheets[index].rules until it is no longer undefined (where index of course is the index of the newly inserted file). Unfortunately his code is buggy and only works with Safari & FF. So I fixed the bugs, added functionality for Opera and Internet Explorer and even added features for adding multiple CSS and JS files and 1 final callback (when all files are loaded) in a sweet and simple lazyloader-function. The result can be found here:

https://github.com/LukasBombach/Lazyloader

How to determine if CSS has been loaded?

After doing some research and writing up my answer, I stumbled upon this link that explains everything you need to know about CSS, when it is loaded and how you can check for it.

The link provided explains it so well, in fact, that I'm adding some quotes from it for future reference.

If you're curious, my answer was going to be #2 and a variation of #4.

When is a stylesheet really loaded?

...

With that out of the way, let's see what we have here.

// my callback function 
// which relies on CSS being loaded function
CSSDone() {
alert('zOMG, CSS is done');
};

// load me some stylesheet
var url = "http://tools.w3clubs.com/pagr/1.sleep-1.css",
head = document.getElementsByTagName('head')[0],
link = document.createElement('link');

link.type = "text/css";
link.rel = "stylesheet";
link.href = url;

// MAGIC
// call CSSDone() when CSS arrives
head.appendChild(link);

Options for the magic part, sorted from nice-and-easy to ridiculous

  1. listen to link.onload
  2. listen to link.addEventListener('load')
  3. listen to link.onreadystatechange
  4. setTimeout and check for changes in document.styleSheets
  5. setTimeout and check for changes in the styling of a specific element you create but style with the new CSS

5th option is too crazy and assumes you have control over the content of the CSS, so forget it. Plus it checks for current styles in a timeout meaning it will flush the reflow queue and can be potentially slow. The slower the CSS to arrive, the more reflows. So, really, forget it.

So how about implementing the magic?

// MAGIC 

// #1
link.onload = function () {
CSSDone('onload listener');
};

// #2
if (link.addEventListener) {
link.addEventListener('load', function() {
CSSDone("DOM's load event");
}, false);
};

// #3
link.onreadystatechange = function() {
var state = link.readyState;
if (state === 'loaded' || state === 'complete') {
link.onreadystatechange = null;
CSSDone("onreadystatechange");
}
};

// #4
var cssnum = document.styleSheets.length;
var ti = setInterval(function() {
if (document.styleSheets.length > cssnum) {
// needs more work when you load a bunch of CSS files quickly
// e.g. loop from cssnum to the new length, looking
// for the document.styleSheets[n].href === url
// ...

// FF changes the length prematurely :(
CSSDone('listening to styleSheets.length change');
clearInterval(ti);
}
}, 10);

// MAGIC ends

HOW TO check if an external (cross-domain) CSS file is loaded using Javascript

This is actually what I did.

To ensure a specific CSS file is loaded, I added a style in the end of the CSS file. For example:

#ensure-cssload-8473649 {
display: none
}

Now I have a JavaScript function which will fire the callback specified when the above style is loaded on the page:

var onCssLoad = function (options, callback) {
var body = $("body");
var div = document.createElement(constants.TAG_DIV);
for (var key in options) {
if (options.hasOwnProperty(key)) {
if (key.toLowerCase() === "css") {
continue;
}
div[key] = options[key];
}
}

var css = options.css;
if (css) {
body.appendChild(div);
var handle = -1;
handle = window.setInterval(function () {
var match = true;
for (var key in css) {
if (css.hasOwnProperty(key)) {
match = match && utils.getStyle(div, key) === css[key];
}
}

if (match === true) {
window.clearTimeout(handle);
body.removeChild(div);
callback();
}
}, 100);
}
}

And this is how I used the function above:

onCssLoad({
"id": "ensure-cssload-8473649",
css: {
display: "none"
}
}, function () {
// code when you want to execute
// after your CSS file is loaded
});

Here the 1st parameter takes the options where id is to check against the test style and css property to verify against what loaded from the CSS.



Related Topics



Leave a reply



Submit