【问题标题】:Why "document.styleSheets" returns empty value after each 3 to 5 browser refreshes?为什么“document.styleSheets”在每 3 到 5 次浏览器刷新后返回空值?
【发布时间】:2014-12-26 21:08:18
【问题描述】:

我想要实现的是让用户定义要由我编写的 JavaScript 文件处理的特定样式表,这是我用来获取指定样式表的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="sheet-1.css">
    <link rel="stylesheet" href="sheet-2.css">
    <link rel="stylesheet" href="sheet-3.css">
    <!-- other css files -->

    <style>
        /* inline styles */
    </style>

</head>
<body>

    <script src="jquery-2.1.1.min.js"></script>
    <!-- some plugins -->

    <script>
        jQuery(document).ready(function($) {

            // user specified stylesheets
            var watchedStyleSheetsNames = [ 'sheet-1.css', 'sheet-2.css', 'sheet-3.css' ]

            var allSheets    = document.styleSheets,
                targetSheets = [];

            for ( var i = watchedStyleSheetsNames.length - 1; i >= 0; i--) {
                Object.keys( allSheets ).forEach ( function (j) {
                    if( allSheets[j].href && allSheets[j].href.indexOf( watchedStyleSheetsNames[i] ) !== -1 ) {
                        targetSheets.push(allSheets[j]);
                    }

                });            

            };

            // result
            console.log( 'Watched Stylesheets Array : ' + targetSheets );

        });
    </script>
</body>
</html>



问题是在第一次页面加载时一切正常,然后在 3 到 5 次刷新 targetSheets 数组后返回空值,这显然会破坏之后完成的所有操作,然后再刷新一次我得到期望值等等。我尝试了所有浏览器,清除了我的缓存,同样的事情一次又一次地发生。这是我在控制台中得到的图像:

https://www.dropbox.com/s/ipnc20hcdr3d6wl/01.png?dl=0

我在所有浏览器的最新版本中使用 wamp 服务器在线和本地测试了我的代码。那么是什么导致了这个问题,我该如何解决呢?

感谢您的宝贵时间。

编辑

我找到了答案,因为实现了无前缀插件,该插件删除了链接节点,然后将处理后的 css 重新插入到样式标签中。

【问题讨论】:

  • 听起来像是一种竞争条件。要验证它的竞争条件,请将该函数置于 setTimeout 中 3 秒。看看是否能解决问题。从那里你可能需要研究某种类型的依赖管理,比如 require js。

标签: javascript jquery dom browser prefixfree


【解决方案1】:

您正在从 jQuery ready 处理程序中查找样式表。 jQuery ready 处理程序的全部意义在于它在 HTML 被解析但 所有依赖项都已下载和评估之后触发。显然,有时,您的代码会在样式表加载之前运行。

您需要等到样式表加载完毕。我知道检查链接样式表是否已加载的唯一方法是动态加载它,查看load 事件之前 设置href。可能还有其他方法,我知道的只有这一种。

例如,在您的情况下,您可以从标记中删除 &lt;link&gt; 元素并执行以下操作:

jQuery(document).ready(function($) {

    // user specified stylesheets
    var watchedSheets = [
        { name: 'sheet-1.css' },
        { name: 'sheet-2.css' },
        { name: 'sheet-3.css' }
    ];
    var completed = 0;
    var head = document.querySelector('head');

    watchedSheets.forEach(function(sheet, index) {
        var link = document.createElement('link');
        link.onload  = function() {
            sheet.loaded = true;
            ++completed;
            if (completed === watchedSheets.length) {
                done();
            }
        };
        link.onerror = function() {
            sheet.error = true;
            ++completed;
            if (completed === watchedSheets.length) {
                done();
            }
        };
        link.rel = "styleshet";
        link.href = sheet.name;
        head.appendChild(link);
    });

    function done() {
        var allSheets    = document.styleSheets,
            targetSheets = [];

        Object.keys( allSheets ).forEach ( function (j) {
            var sheet = watchedSheets[j];
            if( !sheet.error && allSheets[j].href && allSheets[j].href.indexOf( sheet.name ) !== -1 ) {
                targetSheets.push(allSheets[j]);
            }
        });            

        // result
        console.log( 'Watched Stylesheets Array : ' + targetSheets );
    }
});

【讨论】:

  • 不幸的是,测试结果表明,即使您的代码仍然存在相同的错误。即使我使用这个插件HERE 动态加载css 并在加载完成后执行代码,同样的错误仍然发生。不知道是什么原因???
  • 当它发生时,您是否在控制台中收到任何错误?加载 CSS 等问题? (CSS 是否被加载?)这听起来像是某种限速或过度活跃的 DDoS 预防措施。
  • 不,我没有收到任何错误。我还尝试将它作为一个函数并在内部使用 setTimeout 并检查数组的空值以每 10 毫秒重复一次代码,直到它获得数组的值但我得到无限循环。我卡住了
  • 这是一个奇怪的情况,即使使用 $(window).load 它给了我与上面相同的结果我想知道可能是什么原因??
猜你喜欢
  • 2016-09-14
  • 1970-01-01
  • 2023-04-05
  • 2021-09-22
  • 2014-02-19
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多