Динамическая загрузка css файла с использованием javascript с обратным вызовом без jQuery

Я пытаюсь загрузить файл css динамически с помощью javascript и не могу использовать какую-либо другую js-библиотеку (например, jQuery).

Загрузка файла css, но я не могу заставить обратный вызов работать для него. Ниже приведен код, который я использую

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

Использование следующего кода для добавления тега script для загрузки файла js работает и вызывает обратный вызов:

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

Я делаю что-то неправильно здесь? Любой другой метод, который может помочь мне в достижении этого, будет высоко оценен?

6 ответов

К сожалению, нет поддержки onload для таблиц стилей в большинстве современных браузеров. Существует решение, которое я нашел с небольшим Googling.

Цитируется по:http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof

Основы

Самая простая реализация этого метода может быть выполнена в рамках 30-ти независимых рамок - кода 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;
}

Это позволит вам загружать таблицу стилей с помощью функции обратного вызова onload следующим образом:

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

Или, если вы хотите, чтобы ваш обратный вызов поддерживал свою область/контекст, вы можете сделать что-то вроде этого:

loadStyleSheet( '/path/to/my/stylesheet.css', this.onComplete, this );


Вы можете сделать пустую ссылку css в своем html файле и указать ссылку ID. например

затем вызовите его с именем ID и измените атрибут 'href'


Некоторое время назад я создал для этого библиотеку, называемую Dysel, надеюсь, что она поможет

Пример: 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
});


Этот ванильный подход JS работает во всех современных браузерах:

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)


Вот как мы это делаем. Используя "requestAnimationFrame" (или отбросьте на простое "load" событие, если оно не получится).

Кстати, именно так Google рекомендует в своем руководстве по скорости страницы: https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery


*******.js может загружать CSS и запускать обратный вызов при завершении. например.

*******([{
 load: "styles.css",
 complete: function() {
 console.log("oooooo. shiny!");
 }
}]);

licensed under cc by-sa 3.0 with attribution.