【问题标题】:Is there any way to detect when a CSS file has been fully loaded?有什么方法可以检测 CSS 文件何时已完全加载?
【发布时间】:2010-12-20 10:03:45
【问题描述】:

我已经测试了很多 JavaScript 和 CSS 的惰性加载器,它们插入

所以我想知道;是否有其他方法可以检测 CSS 文件是否已加载?

【问题讨论】:

  • 我希望有一个非 XHR 解决方案,这样我加载的文件可以被缓存,总体而言,添加/删除文件而不是加载 CSS/JS 和插入/执行它...
  • 这是我所知道的唯一可靠的方法。将数据流式传输到客户端并将其放入style 标记中。
  • (关于问题中的注释,我已删除,关于“在页面底部”的答案。堆栈溢出定期重新排序答案,因此无论底部的答案是否定期更改)。

标签: javascript css lazy-loading


【解决方案1】:

编辑: 应该注意的是,浏览器对 CSS 文件 onload 事件的支持比我最初的回答有所改进。虽然它没有得到完全支持,所以我下面的回答仍然有一些相关性。 Here is a compatibility chart,但不确定来源的合法性。

好的,我终于找到了解决办法。

这个家伙http://tugll.tugraz.at/96784/weblog/9080.html 插入链接标签并轮询 document.styleSheets[index].rules 直到它不再未定义(其中 index 当然是新插入文件的索引)。不幸的是,他的代码有问题,只适用于 Safari 和 FF。因此,我修复了错误,为 Opera 和 Internet Explorer 添加了功能,甚至添加了用于添加多个 CSS 和 JS 文件和 1 个最终回调(当所有文件都加载时)的功能。结果可以在这里找到:

https://github.com/LukasBombach/Lazyloader

【讨论】:

    【解决方案2】:

    值得知道现在当前版本的 Chrome 和 Firefox 会在链接上触发 onload 事件。

    var cssFile = document.createElement("link");
    cssFile.setAttribute("rel", "stylesheet");
    cssFile.setAttribute("type", "text/css");
    // Add event listener
    cssFile.onload = function(){ console.log('loaded'); }
    cssFile.setAttribute("href", 'pathToYour.css');
    document.getElementsByTagName("head")[0].appendChild(cssFile);
    

    【讨论】:

    • onload 事件检测样式表何时完成加载,但在开始应用 CSS 之前触发
    【解决方案3】:

    编辑:(因为可能不支持WebKit)

    所以我宁愿推荐JQuery LOADER

    $("a.button, input.button, button.button").Loader(
    {
        url: [
            'core.css',
            'theme.css',
            'button.css'
        ],
        success: function() {
            $(this).button();
        }
    });
    

    你可以看看LazyLoad JavaScript 库。

    LazyLoad 是一个很小的(仅缩小了 1,541 字节),无依赖 JavaScript 库使它变得超级 易于加载外部 JavaScript 和 (此版本中的新功能)CSS 文件 要求。它非常适合快速和 不显眼地加载大型外部 脚本和样式表要么懒惰 在页面的其余部分之后 完成装载或按需为 需要。

    除了CSS支持,这个版本的LazyLoad还增加了支持 用于并行加载多个 支持它的浏览器中的资源。 加载多个资源 并行,只需传递一组 URL 在单个 LazyLoad cal 中

    【讨论】:

    • 我不会依赖这个:// Gecko and WebKit don't support the onload event on link nodes, so we just have to finish after a brief delay and hope for the best.
    • 我测试了wonko的lazyload。如果您将它与 css 文件一起使用,它会立即触发您的 onload-callback-functions(而不是在 css 完成加载时)。
    • @jAndy:那是个大问题吗?只有一行可以改变它;)如果你使用 jQuery yue 可以使用 ..ready()
    • @sv88erik:我不明白你。我刚刚从源代码中复制了该注释,它基本上告诉我们,该脚本根本没有为问题提供解决方案。
    • @jAndy:啊。我明白你的意思了!但是很容易改变,例如,使用 jQyery 来解决这个问题。
    【解决方案4】:

    尝试在文件末尾添加特定的 CSS 规则并等待 CSS 应用(通过 JavaScript 检查)。之后,您可以确定 CSS 已加载。但是我没有这方面的经验。一个快速的想法可能值得一试。

    【讨论】:

    • 问题在于,如果你有 X 个 css 文件,你需要 X 个不同的 css 规则,那就是一团糟。您还需要管理大量的 css-filecss-rule 关系,并且您可能会用完 CSS 规则。
    • 我同意这一点。实现这一点最舒服的方法可能是编写一个用于加载 CSS 文件的 JS 函数。通过以 CSS 文件名命名的检查器规则,JS 函数可以自行制定规则。我现在没有时间给你举一个简短的例子。
    【解决方案5】:

    我想就可能发生的变化提供一些见解。

    根据 Mozilla 文档 <link> 的最后一段,可以将加载事件附加到 FF 版本 9 及更高版本以及 Chrome 19 及更高版本中的链接元素。没有说明 IE 和 Safari。 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link

    【讨论】:

      【解决方案6】:

      使用像Supply 这样的脚本加载器,它看起来像:

      supply.listen('text/css', function(payload, filename) {
          switch(filename) {
              case: 'foo.css': {
                  // do something
                  break;
              }
              case: 'baseball.css': {
                  break;
              }
              // ...
          }
      });
      
      supply.files({
          stylesheet: [
              'foo.css',
              'baseball.css'
          ]
      });
      

      参考:SupplyJS

      【讨论】:

        【解决方案7】:

        关于“负载检查 CSS 规则”:

        如果,在你的 JS 脚本中,你在你的头部附加了一个包含简单规则的样式标签,比如:#loadingCss { display: block; }

        然后,您只需在所有 CSS 文件中添加如下内容:#loadingCss { display: none; }

        在您的文档的头部,您将样式标签附加到链接标签之前。这样,CSS 文件中的 CSS 规则会更重要(相同的选择器 -> 相同的优先级,文档中的最后一个为获胜者)。

        然后,在您的 JS 脚本中,您只需检查#loadingCss 可见性。 一旦您知道您的 CSS 文件已加载,您就可以删除样式标签。

        对于您要加载的下一个 CSS 文件,您可以在 head 元素的末尾再次添加此样式标记。

        这样,只需一条规则,您就可以管理所有 CSS 文件的加载。 此解决方案的唯一问题是:一次不能加载多个 CSS 文件。但我确信有可能找到一种方法来做到这一点。

        但无论如何,我不确定这个解决方案(使用 CSS 规则检查加载)是否是一个非常好的解决方案。也许还有其他方法可以做到这一点。

        【讨论】:

          【解决方案8】:

          试试这个: 1- 在头部预加载 css

          <link rel="preload" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" as="style" onload="this.rel='stylesheet'"> 
          <link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'"> 
          

          2 - 在页脚预加载 js 文件

              <link rel="preload" as="script" href="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js">
              <link rel="preload" as="script" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
              <link rel="preload" as="script" href="script.js">
          

          3 - 在标签 &lt;/body&gt; 之前添加

          <script>        
          /**  load defer css - js*/  
          // defer css
          var cssAll = document.querySelectorAll('[as="style"]');
          for(i = 0; i < cssAll.length; i++){
              if(cssAll[i].getAttribute("rel") == "preload"){         
                  cssAll[i].setAttribute("rel", "stylesheet");
              }
          }
          //defer js
          var jsAll = document.querySelectorAll('[as="script"]');
          if(!window.jQuery)
          {
              // load jquery lib
              var script = document.createElement('script');
              script.type = "text/javascript";
              script.src = jsAll[0].getAttribute("href");
              document.getElementsByTagName('head')[0].appendChild(script);
             // load other lib after load jquery
              script.onload = function () {
                  for(i = 1; i < jsAll.length; i++){
                      var jsNext = document.createElement('script');
                      jsNext.type = "text/javascript";
                      jsNext.src = jsAll[i].getAttribute("href");
                      document.getElementsByTagName('head')[0].appendChild(jsNext);
                  }
              }   
          }
          </script>   
          

          我在firefox 57、chrome 61、yandex上测试过,没在opera和ie上测试过

          【讨论】:

            【解决方案9】:

            这是迄今为止我发现的最简单、最好的解决方案,而且效果很好:

            var head = document.getElementsByTagName('head')[0];
            var link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = css_url;
            
            head.appendChild(link);
            
            var img = document.createElement('img');
            document.body.appendChild(img);
            
            img.onerror = img.onload = function() {
                img.onerror = img.onload = null;
                document.body.removeChild(img);
                // do whatever you need to do when css loaded;
            };
            
            img.src = css_url;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-11-09
              • 1970-01-01
              • 2013-03-10
              • 2018-04-14
              • 2013-06-27
              • 2011-09-19
              • 2014-11-29
              相关资源
              最近更新 更多