我正在尝试使用javascript动态加载css文件,不能使用任何其他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 );
使用以下代码添加脚本标记以加载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 );
我在这里做错了吗?任何其他可以帮助我实现这一目标的方法都会受到赞赏吗?
答案 0 :(得分:37)
不幸的是,在大多数现代浏览器中,样式表没有onload支持。我用一点谷歌搜索找到了一个解决方案。
引自: 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 );
答案 1 :(得分:5)
您可以在html文件中创建一个空的css链接,并为该链接指定一个ID。 e.g
<link id="stylesheet_css" rel="stylesheet" type="text/css" href="css/dummy.css?"/>
然后用ID名称调用它并更改'href'属性
答案 2 :(得分:5)
前段时间我为此创建了一个图书馆,它被称为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
});
答案 3 :(得分:4)
这种vanilla 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)
答案 4 :(得分:1)
这是我们如何做到的。使用“requestAnimationFrame”(如果无效,则回退到简单的“加载”事件)。
顺便说一句,这是谷歌推荐的“页速”手册: 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>
答案 5 :(得分:0)
yepnope.js可以加载CSS并在完成时运行回调。 e.g。
yepnope([{
load: "styles.css",
complete: function() {
console.log("oooooo. shiny!");
}
}]);
答案 6 :(得分:0)
针对旧问题的新答案:
您可以简单地使用AJAX请求CSS文件的文本并将其放在<style>
标记中。将样式添加到DOM后,即可立即使用。
这是我想出的一个脚本:
/**
* Given a URL for a JS or CSS file, this function will
* load the asset and return a Promise which will reject
* on error or resolve when the asset is loaded.
*/
function loadAsset(url){
return new Promise(async (resolve, reject)=>{
var asset;
if(url.trim().substr(-3).toLowerCase() === '.js'){
asset = document.createElement('script');
asset.addEventListener('load', resolve);
asset.addEventListener('error', reject);
document.head.appendChild(asset);
asset.setAttribute('src', url);
}else{
var styles = await fetch(url)
.then(c=>c.text())
.catch(reject);
asset = document.createElement('style');
asset.appendChild(document.createTextNode(styles));
document.head.appendChild(asset);
resolve();
}
});
}