使用带有回调的 javascript 动态加载 css 文件,无需 jQuery

发布于 2024-10-30 04:13:35 字数 917 浏览 5 评论 0原文

我正在尝试使用 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 );

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

酒解孤独 2024-11-06 04:13:35

不幸的是,大多数现代浏览器都不支持样式表加载。我通过谷歌搜索找到了一个解决方案。

引用自: 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 );

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 basics

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 );
最笨的告白 2024-11-06 04:13:35

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

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)
一身仙ぐ女味 2024-11-06 04:13:35

前段时间我为此创建了一个库,它的名字是 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
});

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
});
傲影 2024-11-06 04:13:35

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

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

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

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

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

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

瀟灑尐姊 2024-11-06 04:13:35

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

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

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

yepnope([{
  load: "styles.css",
  complete: function() {
    console.log("oooooo. shiny!");
  }
}]);
番薯 2024-11-06 04:13:35

我们是这样做的。通过使用“requestAnimationFrame”(如果无效,则回退到简单的“load”事件)。

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

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

By the way, this is the way Google recommends in their "page-speed" manual:
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>
情魔剑神 2024-11-06 04:13:35

老问题的新答案:

您可以简单地使用 AJAX 请求 CSS 文件的文本并将其放入

这是我想出的一个脚本:

/**
 * 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();
    }
  });
}

New answer to an old question:

You can simply request the text of the CSS file with AJAX and put it in a <style> tag. When the styles have been appended to the DOM they are available immediately.

Here's a script I came up with:

/**
 * 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();
    }
  });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文