$ .get如何获取多个CSS文件内容?

时间:2018-07-11 16:31:29

标签: javascript jquery jquery-deferred

我可以这样获取单个css文件的内容

getStyleCSS = $.get("MyStyle.css");
$.when(getStyleCSS).done(function(response) {
    var strCSS = response; // response here is the text content of the css file
}

但是当我尝试获取多个这样的css文件内容时,我得到的是Deferred对象而不是css内容。

// Get a handle on an aspx created element which contains css script elements
var elementDiv = document.getElementById('somediv');

// Get the stylesheets from this element
var links= elementDiv.getElementsByTagName('link');
arrLinks = [];
arrDeferreds = [];

// jQuery get each of the css links
for (var i = 0; i < arrLinks.length; i++) {
    var link = arrLinks[i];
    arrDeferreds.push($.get(link));
}

// Fetch the css documents
$.when(arrDeferreds).done(function (response) {
    var result = response; // response here is an array of Deferred objects
}

是否可以使用javascript / jQuery获取多个CSS文件的文本内容?

上下文: 我需要将页面HTML的子集发送到外部(跨站点)服务,该服务将生成指定HTML的PDF。为了正确生成pdf,我需要将所有CSS内容的文本嵌入到html中。页面内容源自aspx / ascx控件,其中一些控件包含指向各种css文件的脚本元素。我正在尝试获取每个元素的CSS文本内容。

2 个答案:

答案 0 :(得分:2)

这并不是真正的解决方案(我仍然没有弄清楚如何从Deferred对象获取结果),但这似乎是一个合法的解决方法。感谢@AussieJoe提供指向另一个stackoverflow答案的指针。

我可以像这样在页面上为所有css建立css字符串

var strCSS = '';
for (var i = 0; i < document.styleSheets.length; i++) {
    var stylesheet = document.styleSheets[i];
    for (var j = 0; j < stylesheet.cssRules.length; j++) {
        var rule = stylesheet.cssRules[j];
        strCSS += rule.cssText;
    }
}

答案 1 :(得分:2)

您的代码有一个问题,就是$.when()不接受一组递延/承诺作为参数。来自the jQuery doc

  

如果将单个参数传递给jQuery.when(),而不是Deferred或Promise,它将被视为已解析的Deferred,任何附加的doneCallbacks都将立即执行。

因此,传递一个递延数组,只会使您立即返回数组。

相反,它需要将它们作为单独的参数传递,并将结果作为单独的参数提供给.done(),如下所示:

$.when(d1, d2, d3).then(function(r1, r2, r3) {
    console.log(r1, r2, r3);
});

如果像在代码中那样在数组中包含延迟,则可以使用.apply()来传递它们。而且,结果不会再次以数组的形式提供给您,而是以.done()的一系列单独参数提供给您(同样,非常不便)。

因此,您可以更改以下代码:

// jQuery get each of the css links
for (var i = 0; i < arrLinks.length; i++) {
    var link = arrLinks[i];
    arrDeferreds.push($.get(link));
}

// Fetch the css documents
$.when(arrDeferreds).done(function (response) {
    var result = response; // response here is an array of Deferred objects
}

对此:

// jQuery get each of the css links
for (var i = 0; i < arrLinks.length; i++) {
    var link = arrLinks[i];
    arrDeferreds.push($.get(link));
}

// Fetch the css documents
$.when.apply($, arrDeferreds).done(function() {
    // copy arguments object into an actual array
    let results = Array.prototype.slice.call(arguments);
    console.log(results);
}

或者,在ES6中,您可以只使用使用数组的Promise.all()

// Fetch the css documents
Promise.all(arrDeferreds).then(function(results) {
    console.log(results);
});

长话短说,在任何现代Javascript环境中,请使用Promise.all()而不是$.when()


仅供参考,如果您不能使用Promise.all()或polyfill,那么我不久前开发了此$.all()实现,可以使用数组:

// jQuery replacement for $.when() that works like Promise.all()
// Takes an array of promises and always returns an array of results, even if only one result
$.all = function(promises) {
    if (!Array.isArray(promises)) {
        throw new Error("$.all() must be passed an array of promises");
    }
    return $.when.apply($, promises).done(function () {
        // if single argument was expanded into multiple arguments, then put it back into an array
        // for consistency
        var args = Array.prototype.slice.call(arguments, 0);
        if (promises.length === 1 && arguments.length > 1) {
            // put arguments into an array for consistency
            return [args];
        } else {
            return args;
        }
    });
};