2010-12-20 53 views
30

我一直在测试很多是插入<脚本>和<链接>标签加载文件懒装载机JavaScript和CSS的。然而,问题是,<link>标签不火onload所以很难他们加载时被发现。我发现这种情况的唯一解决方法是设置display: none;(在CSS文件将被加载)一个哑元上查询该元素时,它已经被设置为显示检查:无。但是,除了丑陋之外,当然只适用于单个CSS文件。有什么方法可以检测CSS文件何时被完全加载?

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

+2

检查了这一点:https://github.com/jAndreas/Supply – jAndy 2010-12-20 10:10:42

+0

我希望非XHR解决方案,所以我加载的文件可能是缓存和整体它*感觉*更清洁添加/删除文件,而不是加载CSS/JS和插入/执行它... – Lukas 2010-12-20 10:55:18

+0

这是我知道的唯一可靠的方法。将数据流传输到客户端并将其放入'style'标签。 – jAndy 2010-12-20 11:32:39

回答

15

编辑:应该指出的是,自从我原来的答案以来,浏览器对CSS文件onload事件的支持有所改进。尽管如此,我的回答仍然有一些相关性。 Here is a compatibility chart,不知道该来源是多么合法。

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

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

https://github.com/LukasBombach/Lazyloader

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是一个很小的(精缩仅1541字节),依赖自由 JavaScript库,使用户能够无比轻松 上加载 需求外部JavaScript和 (新的版本)的CSS文件。这是快速和 悄悄加载大型外部 脚本和样式表要么懒惰地 后页面的其余部分已 完成加载或按需 需要。

除了CSS支持,此版本的LazyLoad还增加了支持 的并行加载多个支持它的浏览器中的 资源。 要 并行加载多个资源,只需通过网址 阵列在一个单一的LazyLoad CAL

+2

我不会依赖这个:'// Gecko和WebKit不支持链接节点上的onload事件,所以我们只需要在短暂的延迟之后完成并且希望最好。' – jAndy 2010-12-20 10:20:44

+0

我测试了wonko的lazyload。它会立即启动onload-callback-funtions(而不是在css完成加载时),如果将它用于css文件。 – Lukas 2010-12-20 10:27:45

+0

@jAndy:那么这是个大问题吗?只有一行可以改变它;)如果你使用jQuery yue,可以使用..ready() – sv88erik 2010-12-20 10:33:05

3

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

+0

问题在于,如果你有X css文件,你需要X个不同的CSS规则,那是一团糟。此外,您还需要管理大量的css文件<-> css-rule关系,并且您可能会用完CSS规则。 – Lukas 2010-12-20 10:35:19

+0

我同意这一点。实现这个最舒服的方法可能是编写一个用于加载CSS文件的JS函数。通过以CSS文件名命名检查器规则,JS函数可以计算出规则本身。我现在没有时间给你一个简短的例子。 – 2010-12-20 10:44:34

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

1

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

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

比,你只需要添加你所有的CSS文件,如:#loadingCss {display:none; }

在文档的头部,您可以在链接标记前追加样式标记。这样一来,在CSS文件中的CSS规则将是更重要的(相同的选择 - >相同的优先级,最后一个在doc是赢家)。

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

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

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

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

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); 
0

试试这个:在头 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> 

我测试过o ñ火狐57,铬61,yandex,未在歌剧和测试

相关问题