jQuery:如果完成,按需加载css +回调

我想按需加载CSS文件(通过例如运行XML HTTP请求,返回要加载的CSS文件),例如style1.cssstyle2.css ..

那么jQuery(或插件)中有一种方法吗?

  • 批量加载多个文件+将所有这些CSS文件添加到dom中
  • 完成加载时:触发回调(如警告“所有样式表已完成加载!”);

这个想法是:通过xmlhttp加载html ,加载+添加所需的 css文件,然后 – 在完成任何事情后,显示该html

任何的想法?

感谢名单!

如何使用所请求的回调加载多个 CSS文件
请注意,如果没有xdomain权限,$ .get将只加载本地文件

工作演示

 $.extend({ getCss: function(urls, callback, nocache){ if (typeof nocache=='undefined') nocache=false; // default don't refresh $.when( $.each(urls, function(i, url){ if (nocache) url += '?_ts=' + new Date().getTime(); // refresh? $.ajax({ url: url, cache: true, // set this to false if each CSS file // must refresh and not use a cached version success: function(){ $('', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head'); } }); }) ).then(function(){ if (typeof callback=='function') callback(); }); }, }); 

var cssfiles = [‘/ css / normalize.css?jobofferinsidebar’,’/ css / trip.css?jobofferinsidebar’];

$ .getCss(cssfiles,function(){console.log(’all css loaded’);}); 用法

 var cssfiles=['/css/normalize.css', '/css/tricks.css']; $.getManyCss(cssfiles, function(){ // do something, eg console.log('all css loaded'); }); 

强制刷新css文件添加true

 $.getManyCss(cssfiles, function(){ // do something, eg console.log('all css loaded'); }, true); 

@Popnoodles给出的答案是不正确的,因为在加载所有项之后不执行回调,而是在$ .each循环完成时执行。 原因是, $.each操作不返回Deferred对象( $.each预期)。

这是一个更正的例子:

 $.extend({ getCss: function(urls, callback, nocache){ if (typeof nocache=='undefined') nocache=false; // default don't refresh $.when.apply($, $.map(urls, function(url){ if (nocache) url += '?_ts=' + new Date().getTime(); // refresh? return $.get(url, function(){ $('', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head'); }); }) ).then(function(){ if (typeof callback=='function') callback(); }); } }); 

我将如何加载它:

 $(document).ready( function() { var css = jQuery(""); css.attr({ rel: "stylesheet", type: "text/css", href: "path/to/file/style.css" }); $("head").append(css); }); 

您正在尝试实现资源的延迟加载。 有不同的插件来处理这种行为。

我可以说出这两个名字:

  • Jquery插件

来自插件页面的两个片段显示它的用途:

Jquery插件

 $.plugins({ path: '/scripts/', plugins: [ { id:'box', js:'box.js', css:'box/styles.css', sel:'a[rel*=box]', ext:'box', fn:'box' }, ]}); jQuery(document).ready(function($){ $('a').box(); }); 

懒惰的依赖项:

 $.lazy('ui.draggable.js','draggable',{ 'css':['modal.css','drag.css'], 'js':['ui.core.js'] }); // And then you use you plugins as you always do $("#draggable").draggable(); 

我认为解决方案可以改进一点……首先,当你使用这行代码时:

 ... $.get(url, function(){ $('', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head'); }); ... 

你真的要进行2次调用来检索css:首先是在$.get本身,第二次是将追加到head 。 删除$.get也将检索css,但只需检索一次:

 ... $('', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head'); ... 

但是如果你在调用回调函数之前需要做更多事情(例如加载脚本文件)同时检索这些css’,我认为更好的方法是使用promises而不是when...then解决方案。 你可以这样做:

 var requests = []; //array which will contain every request we want to do before calling the callback function $.map(urls, function(url) { //urls is the array of css files we want to load var defer = $.Deferred(); defer.promise(); //we add the deferred object to the requests array requests.push(defer); var cssEl = $('', { rel: 'stylesheet', type: 'text/css', 'href': url }); cssEl.appendTo('head').on("load", function() { defer.resolve(); }); }); var anotherRequest = $.ajax({...}); //eg. a script file requests.push(anotherRequest); $.when.apply($, requests).done(function() { // callback when all requests are done }); 

这样,如果某些css需要一些时间来加载,则在检索所有css之前不会执行回调函数。

如果要加载多个CSS文件,但希望逐个加载它们,可以使用以下解决方案:

 var getCss = function (url, callback) { $.get(url, function () { $('', {rel: 'stylesheet', type: 'text/css', 'href': url}).appendTo('head'); if (typeof callback == 'function') callback(); }); }; 

定义上面的函数,然后定义包含你想要的css文件的数组

 var cssfiles = ['css/pic1.css', 'css/pic2.css', 'css/pic3.css', 'css/pic4.css', 'css/pic5.css', 'css/pic6.css', 'css/pic7.css', 'css/pic8.css', 'css/pic9.css']; 

然后定义将调用数组中每个css文件的回调函数

 var callback = function (index) { getCss(cssfiles[index], function () { if (index + 1 < cssfiles.length) { callback(index + 1); } }); }; 

然后通过给出索引来启动第一个css文件的函数

 callback(0); 

如果你想通过动态(读取:按需),你可以修改Whit对loadCssFile()的响应,并使用你想要加载的文件调用它。

 function loadCssFile(pathToFile) { var css = jQuery(""); css.attr({ rel: "stylesheet", type: "text/css", href: pathToFile }); $("head").append(css); } 

这不需要CSS文件(S)加载超过一次

从其他已建立的答案开始,我设法得到了这个,它似乎与jQuery.getScript()类似:

 (function($){ $.extend({ getCss: function(url, success) { if ($("head").children("style[data-url='"+url+"']").length) { console.warn("CSS file already loaded: "+url); } var deferred = $.Deferred(function(defer){ $.ajax({ url: url ,context: {defer:defer,url:url} ,dataType: 'text' ,cache: (function(){ var cache = $.ajaxSetup().cache; if (cache === undefined) {cache = false;} return cache; })() }) .then( function(css, textStatus, jqXHR){ css = "\n\n/* CSS dynamically loaded by jQuery */\n\n"+css; $('').appendTo("head"); this.defer.resolve(css, textStatus, jqXHR); } ,function(jqXHR, textStatus, errorThrown){ this.defer.reject(jqXHR, textStatus, errorThrown); } ); }); if ($.isFunction(success)) {deferred.done(success);} return deferred; } }); })(jQuery); 

它不会多次加载所请求的文件,这需要将CSS内容静态存储在头部。 但是,考虑到加载/评估JavaScript与浏览器可以访问样式的方式不同,这是有道理的。

 $.getCss('path/to/css/file.css') .done(function(){ console.log("Worked"); }) .fail(function(){ console.log("Failed"); }); 

到目前为止,我已经使用Chrome,IE和Firefox对其进行了测试。 一切似乎都很好。