繁体   English   中英

在Chrome document.styleSheets上,当我添加样式表时不会更新

[英]On Chrome document.styleSheets is not updated when I add a stylesheet

显然,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上无法运行。

您正在添加一个外部文件,然后立即对其进行检查。 您不会看到它也就不足为奇了,HTTP请求可能仍然未完成。 如果稍后再检查,则在HTTP请求完成并且解析并应用了样式之后,您将在document.styleSheets看到它。

根据HTML5规范 ,您可以在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 ,这会更简洁一些。在所有现代浏览器以及IE8上都支持querySelector / querySelectorAll 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM