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

IT技术 javascript css callback loading
2021-02-25 17:27:33

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

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

6个回答

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

引自: 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 );
谢谢我也遇到了另一篇博客文章,在这里也提出了同样的建议 基本上是使用计时器来检查头部的所有脚本,看看是否加载了所需的脚本。
2021-05-09 17:27:33
他页面上的选项 #2 似乎是一个更好的解决方案:“使用 AJAX 加载样式表的内容,创建样式节点并将 XHR responseText 插入样式节点。”
2021-05-11 17:27:33
这将导致 IE7 或更高版本自动停止脚本。所以不会触发回调。
2021-05-17 17:27:33
非常有帮助,解决了我只在 Safari 浏览器中遇到的问题。
2021-05-19 17:27:33
当我尝试执行它时,它总是返回 false,尽管样式表加载得很好。在调试时,我发现它link[sheet]总是返回 null。你有什么想法吗
2021-05-20 17:27:33

这种普通的 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)
工作完美,ES6 与我的 Angular typescript应用程序相处得很好!
2021-05-07 17:27:33
发布问题时,即使使用 ES6 Polyfill,也无法在 iOS、Android、Chrome 或 Safari 中工作,并且仍然无法在未打补丁的系统(例如,非常多的用户手机)上的这些浏览器中工作 - WebKit 只有非常最近添加了loadlink元素事件的支持
2021-05-20 17:27:33

前段时间我为此创建了一个库,名为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
});
很棒的家伙,另一个图书馆添加到我的“必须”中;)谢谢
2021-04-27 17:27:33

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

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

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

我无权访问页面的 html。我只能编辑第 3 方 html 页面正在加载的 javascript。所以解决方案需要基于javascript。但是谢谢你的想法。
2021-05-10 17:27:33

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

yepnope([{
  load: "styles.css",
  complete: function() {
    console.log("oooooo. shiny!");
  }
}]);
它在插入链接元素时运行回调。
2021-05-21 17:27:33