Dynamically loading css file using javascript with callback without jQuery
Unfortunately there is no onload support for stylesheets in most modern browsers. There is a solution I found with a little Googling.
Cited from: http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof
The basics
The most basic implementation of this can be done in a measely 30 lines of — framework independent — JavaScript code:
function loadStyleSheet( path, fn, scope ) {
var head = document.getElementsByTagName( 'head' )[0], // reference to document.head for appending/ removing link nodes
link = document.createElement( 'link' ); // create the link node
link.setAttribute( 'href', path );
link.setAttribute( 'rel', 'stylesheet' );
link.setAttribute( 'type', 'text/css' );
var sheet, cssRules;
// get the correct properties to check for depending on the browser
if ( 'sheet' in link ) {
sheet = 'sheet'; cssRules = 'cssRules';
}
else {
sheet = 'styleSheet'; cssRules = 'rules';
}
var interval_id = setInterval( function() { // start checking whether the style sheet has successfully loaded
try {
if ( link[sheet] && link[sheet][cssRules].length ) { // SUCCESS! our style sheet has loaded
clearInterval( interval_id ); // clear the counters
clearTimeout( timeout_id );
fn.call( scope || window, true, link ); // fire the callback with success == true
}
} catch( e ) {} finally {}
}, 10 ), // how often to check if the stylesheet is loaded
timeout_id = setTimeout( function() { // start counting down till fail
clearInterval( interval_id ); // clear the counters
clearTimeout( timeout_id );
head.removeChild( link ); // since the style sheet didn't load, remove the link node from the DOM
fn.call( scope || window, false, link ); // fire the callback with success == false
}, 15000 ); // how long to wait before failing
head.appendChild( link ); // insert the link node into the DOM and start loading the style sheet
return link; // return the link node;
}
This would allow you to load a style sheet with an onload callback function like this:
loadStyleSheet( '/path/to/my/stylesheet.css', function( success, link ) {
if ( success ) {
// code to execute if the style sheet was loaded successfully
}
else {
// code to execute if the style sheet failed to successfully
}
} );
Or if you want to your callback to maintain its scope/ context, you could do something kind of like this:
loadStyleSheet( '/path/to/my/stylesheet.css', this.onComplete, this );
This vanilla JS approach works in all modern browsers:
let loadStyle = function(url) {
return new Promise((resolve, reject) => {
let link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.onload = () => { resolve(); console.log('style has loaded'); };
link.href = url;
let headScript = document.querySelector('script');
headScript.parentNode.insertBefore(link, headScript);
});
};
// works in IE 10, 11 and Safari/Chrome/Firefox/Edge
// add an ES6 polyfill for the Promise (or rewrite to use a callback)
Some time ago i made a library for this, it's called Dysel, i hope it helps
Example: https://jsfiddle.net/sunrising/qk0ybtnb/
var googleFont = 'https://fonts.googleapis.com/css?family=Lobster';
var jquery = 'https://code.jquery.com/jquery.js';
var bootstrapCss = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css';
var bootstrapJs = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js';
var smokeCss = 'https://rawgit.com/alfredobarron/smoke/master/dist/css/smoke.min.css';
var smokeJs = 'https://rawgit.com/alfredobarron/smoke/master/dist/js/smoke.min.js';
// push links into an array in the correct order
var extRes = [];
extRes.push(googleFont);
extRes.push(bootstrapCss);
extRes.push(smokeCss);
extRes.push(jquery);
extRes.push(bootstrapJs);
extRes.push(smokeJs);
// let this happen
dysel({
links: extRes,
callback: function() {
alert('everything is now loaded, this is awesome!');
}, // optional
nocache: false, // optional
debug: false // optional
});
You can make an empty css link in your html file and give the link an ID. e.g
<link id="stylesheet_css" rel="stylesheet" type="text/css" href="css/dummy.css?"/>
then call it with ID name and change the 'href' attribute