显然,Google Chrome中的属性document.styleSheets存在问题。添加新样式表后,不会更新该属性。 要重现该问题,只需运行以下代码:
// Create the link element
var element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", "external.css");
// Add the link element
console.log('Before add: ' + document.styleSheets.length);
document.getElementsByTagName("head")[0].appendChild(link);
console.log('After add: ' + document.styleSheets.length);
在FireFox中运行时,控制台将显示如下内容:
Before add: 4
After add: 5
在Chrome中运行时,控制台会显示如下内容:
Before add: 4
After add: 4
有趣的是,以下代码在两个浏览器上都能正常工作(返回相同的结果):
console.log('Before add: ' + document.getElementsByTagName("head")[0].children);
document.getElementsByTagName("head")[0].appendChild(link);
console.log('After add: ' + document.getElementsByTagName("head")[0].children);
这是一个错误还是我做错了什么?
我在编写和测试以下函数时发现了这个问题,以便将CSS文件动态添加到网页中:
function requiresCSS( name ) {
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].href && sheets[i].href.indexOf(name) !== -1) {
return;
}
}
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = name;
document.getElementsByTagName("head")[0].appendChild(link);
}
尝试两次添加CSS时,该功能在Firefox上完美运行,但在Chrome上失败。
答案 0 :(得分:5)
您正在添加外部文件,然后立即进行检查。如果您还没有看到它,这并不奇怪,HTTP请求可能仍然非常出色。如果您稍后再回来查看,一旦HTTP请求完成并解析并应用了样式,您就会在document.styleSheets
中看到它。
根据HTML5 specification,您可以使用link元素上的load
事件来获取资源加载时间的通知。所以:
element.addEventListener("load", function() {
console.log('After add: ' + document.styleSheets.length);
}, false);
console.log('Before add: ' + document.styleSheets.length);
document.getElementsByTagName("head")[0].appendChild(link);
当然,加载和解析/应用可能不是同时发生的,所以如果您仍然看到差异,那么您可能需要setTimeout
:
element.addEventListener("load", function() {
setTimeout(function() {
console.log('After add: ' + document.styleSheets.length);
}, 0);
}, false);
console.log('Before add: ' + document.styleSheets.length);
document.getElementsByTagName("head")[0].appendChild(link);
重新尝试避免添加样式表两次的函数,因为即使document.styleSheets
中的条目不是元素,元素也是可靠的,我只是寻找元素:
function requiresCSS( name ) {
// If we already have an element for this stylesheet, return
if (document.querySelector('link[rel=stylesheet][href="' + name + '"]') {
return;
}
// Add it
var link = document.createElement("link"); link.rel = "stylesheet";
link.type = "text/css"; link.href = name;
document.getElementsByTagName("head")[0].appendChild(link);
}
(您也可以使用querySelector
查找head
,它会更简洁。所有现代浏览器都支持querySelector
/ querySelectorAll
,还有IE8。)