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

时间:2010-08-17 01:23:09

标签: jquery css load

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

在jQuery(或插件)中有这种方式吗?

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

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

任何想法?

感谢名单!

8 个答案:

答案 0 :(得分:23)

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

WORKING DEMO

$.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(){
                        $('<link>', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head');
                    }
                });
            })
        ).then(function(){
            if (typeof callback=='function') callback();
        });
    },
});

var cssfiles=[
  '/css/normalize.css?jobofferinsidebar', 
  '/css/tricks.css?jobofferinsidebar'
];

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

<强>用法:

var cssfiles=['/css/normalize.css', '/css/tricks.css'];

$.getCss(cssfiles, function(){
    // do something, e.g.
    console.log('all css loaded');
});

强制刷新css文件添加true

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

答案 1 :(得分:8)

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

以下是更正后的示例:

$.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(){                    
                    $('<link>', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head');                    
                });
            })
        ).then(function(){
            if (typeof callback=='function') callback();
        });
    }
});

答案 2 :(得分:7)

以下是我加载它的方法:

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

答案 3 :(得分:1)

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

我可以说出这两个名字:

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

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

答案 4 :(得分:1)

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

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

您实际上正在进行2次调用以检索css:首先在$.get本身,第二次将<link>追加到head。删除$.get也会检索css,但只需检索一次:

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

但是如果你需要做更多的事情(例如加载脚本文件),同时检索这些css&#39;在调用回调函数之前,我认为更好的方法是使用 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 = $('<link>', { 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需要一些时间来加载,回调函数将不会被执行,直到所有这些都被检索。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

var getCss = function (url, callback) {
        $.get(url, function () {
            $('<link>', {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);

答案 7 :(得分:0)

这不要求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;
                        $('<style type="text/css" data-url="'+this.url+'">'+css+'</style>').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);

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

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

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