我可以这样获取单个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文本内容。
答案 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;
}
});
};