Javascript 使用带有回调的javascript动态加载css文件而不使用jQuery

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5537622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:42:49  来源:igfitidea点击:

Dynamically loading css file using javascript with callback without jQuery

javascriptcsscallbackloading

提问by U.Ahmad

I am trying to load a css file dynamically using javascript and cannot use any other js library (eg jQuery).

我正在尝试使用 javascript 动态加载 css 文件,并且不能使用任何其他 js 库(例如 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

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

Using the following code to add a script tag to load a js file works and fires a callback:

使用以下代码添加脚本标记以加载 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 );

Am I doing something wrong here? Any other method that can help me achieve this would be much appreciated?

我在这里做错了吗?任何其他可以帮助我实现这一目标的方法将不胜感激?

回答by mVChr

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

引自: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:

最基本的实现可以用 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;
}

This would allow you to load a style sheet with an onload callback function like this:

这将允许您使用 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
   }
} );

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

回答by Alessandro Annini

Some time ago i made a library for this, it's called Dysel, i hope it helps

前段时间我为此创建了一个库,名为Dysel,希望对您有所帮助

Example: https://jsfiddle.net/sunrising/qk0ybtnb/

示例: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
});

回答by sandstrom

This vanilla JS approach works in all modern browsers:

这种普通的 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)

回答by thecodeparadox

You can make an empty css link in your html file and give the link an ID. e.g

您可以在 html 文件中创建一个空的 css 链接并为该链接指定一个 ID。例如

<link id="stylesheet_css" rel="stylesheet" type="text/css" href="css/dummy.css?"/>

then call it with ID name and change the 'href' attribute

然后使用 ID 名称调用它并更改“href”属性

回答by David Palmer

yepnope.jscan load CSS and run a callback on completion. e.g.

yepnope.js可以加载 CSS 并在完成时运行回调。例如

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

回答by Serge Shultz

Here's how we do it. By using "requestAnimationFrame" (or fallback to simple "load" event if its not avail).

这是我们如何做到的。通过使用“requestAnimationFrame”(或回退到简单的“load”事件,如果它不可用)。

By the way, this is the way Google recommends in their "page-speed" manual: https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery

顺便说一句,这是谷歌在他们的“页面速度”手册中推荐的方式: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>