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

How do $.get multiple css file contents?

我可以通过这种方式获取单个 css 文件的内容

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

但是当我尝试像这样获取多个 css 文件内容时,我得到的是延迟对象而不是 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 文本内容。

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

我可以像这样为页面上的所有 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;
    }
}

您的代码存在一个问题,即 $.when() 不接受 deferreds/promises 数组作为参数。来自 the jQuery doc:

If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.

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

相反,它需要将它们作为单独的参数传递,并将结果作为单独的参数提供给 .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;
        }
    });
};