J'essaie de charger un fichier css de manière dynamique en utilisant javascript et je ne peux utiliser aucune autre bibliothèque js (par exemple, jQuery).
Le fichier css est chargé mais je n'arrive pas à obtenir un rappel pour travailler. Ci-dessous le code que j'utilise
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 );
L'utilisation du code suivant pour ajouter une balise de script afin de charger un fichier js fonctionne et déclenche un rappel:
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 );
Est-ce que je fais quelque chose de mal ici? Toute autre méthode qui pourrait m'aider à atteindre cet objectif serait très appréciée?
Malheureusement, la plupart des navigateurs modernes ne prennent pas en charge les feuilles de style avec précaution. Il y a une solution que j'ai trouvée avec un peu de googling.
Cited from: _ http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof
L'implémentation la plus élémentaire de ceci peut être réalisée dans une trentaine de lignes de - code indépendant du framework - JavaScript:
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;
}
Cela vous permettrait de charger une feuille de style avec une fonction de rappel onload comme ceci:
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
}
} );
Ou si vous souhaitez que votre rappel conserve son périmètre/contexte, vous pouvez procéder de la sorte:
loadStyleSheet( '/path/to/my/stylesheet.css', this.onComplete, this );
Vous pouvez créer un lien css vide dans votre fichier html et lui attribuer un identifiant. par exemple
<link id="stylesheet_css" rel="stylesheet" type="text/css" href="css/dummy.css?"/>
puis appelez-le avec le nom de l'ID et changez l'attribut 'href'
Il y a quelque temps, j'ai créé une bibliothèque pour cela, elle s'appelle Dysel , j'espère que ça aide
Exemple: 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
});
Cette approche Vanilla JS fonctionne dans tous les navigateurs modernes:
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)
Voici comment nous le faisons. En utilisant "requestAnimationFrame" (ou faites appel à un simple événement "load" si ce n'est pas le cas).
Soit dit en passant, c’est ce que recommande Google dans son manuel "Page-speed": https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery }
<script>
function LoadCssFile(cssPath) {
var l = document.createElement('link'); l.rel = 'stylesheet'; l.href = cssPath;
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
}
var cb = function() {
LoadCssFile('file1.css');
LoadCssFile('file2.css');
};
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
yepnope.js peut charger CSS et exécuter un rappel à la fin. par exemple.
yepnope([{
load: "styles.css",
complete: function() {
console.log("oooooo. shiny!");
}
}]);