有没有办法检测CSS文件何时完全加载?

时间:2010-12-20 10:03:45

标签: javascript css lazy-loading

我一直在测试很多用于JavaScript和CSS的懒惰加载器,它们插入&lt; script&gt;和&lt; link&gt;用于加载文件的标签。但问题是,<link>标记不会触发onload,因此很难检测到它们何时被加载。我找到的唯一解决方法是在虚拟元素上设置display: none;(在要加载的CSS文件中)并轮询该元素以检查它何时设置为display:none。但是,除了丑陋之外,当然只适用于单个CSS文件。

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

9 个答案:

答案 0 :(得分:16)

编辑: 应该注意的是,自我的原始答案以来,浏览器对CSS文件上的onload事件的支持有所改进。虽然它没有完全支持,所以我的答案仍然有一些相关性。 Here is a compatibility chart,但不确定来源是多么合法。

好的,我终于找到了解决方案。

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

https://github.com/LukasBombach/Lazyloader

答案 1 :(得分: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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

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

答案 4 :(得分: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);

答案 5 :(得分:1)

使用像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

答案 6 :(得分:1)

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

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

然而,你只需添加所有CSS文件,例如:#loadingCss {display:none; }

在doc的头部,您可以在link标记之前附加样式标记。这样,CSS文件中的CSS规则将更加重要(相同的选择器 - &gt;相同的优先级,文档中的最后一个是赢家)。

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

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

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

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

答案 7 :(得分:1)

试试这个: 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 - 在标记</body>添加

之前
<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上测试,即

答案 8 :(得分:0)

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

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;