I am trying to load a css file dynamically using javascript and cannot use any other js library (eg jQuery).
The css file loads but I can't seem to get a callback to work for it. Below is the code I am using
var callbackFunc = function(){
console.log('file loaded');
};
var head = document.getElementsByTagName( "head" )[0];
var fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", url);
fileref.onload = callbackFunc;
head.insertBefore( fileref, head.firstChild );
Using the following code to add a script tag to load a js file works and fires a callback:
var callbackFunc = function(){
console.log('file loaded');
};
var script = document.createElement("script");
script.setAttribute("src",url);
script.setAttribute("type","text/javascript");
script.onload = callbackFunc ;
head.insertBefore( script, head.firstChild );
Am I doing something wrong here? Any other method that can help me achieve this would be much appreciated?
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 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
});
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