我目前正在开发一个移动网站,其中包含大量图片,css和javascript(例如,使用150KB未压缩的库).我为图像构造了一个预加载器,效果很好:
function loadImages(images){
var sum = 0;
for(i in images){
sum += images[i][1]; // file size
}
setMaxProgress(sum);
for(i in imageArray){
var img = new Image();
img.onload = function(){ addProgress(imageArray[i][1]); };
img.src = imageArray[i][0];
}
}
但是,我现在想对javascript和css做类似的事情,但是可用的资源却少得多.我发现的唯一方法是在文档加载后对html标签进行document.write(),但这并不能使我(可靠地)指示何时加载文件.
在我仍然可以衡量进度的同时,有没有办法做到这一点?
顺便说一句:我将它用作常规优化技术的补充,例如最小化js / css,gzipping,css sprite和适当的缓存控制,而不是替代.用户可以跳过加载,然后网站可以正常运行,尽管运行不太顺利
解决方法:
如果您需要知道何时加载JS,请使用以下loadScript函数.您也许可以对CSS进行类似的操作,但是我还没有尝试过:
function preload(src, callback, node)
{
var script,
ready,
where;
where = node || document.body;
ready = false;
script = where.ownerDocument.createElement('script');
script.src = src;
script.onload=script.onreadystatechange=function(){
if ( !ready && ( !this.readyState || this.readyState == 'complete' ) )
{
ready = true;
callback();
script.parentNode.removeChild(script);
}
};
where.appendChild(script);
}
我已经更新了功能,并在firefox中对其进行了测试.它同时适用于js和css(css需要一些跨浏览器检查.
我还想添加一些更多信息,说明为什么要使用script元素来预加载css而不是link元素.
加载页面时,需要分析影响DOM结构的资源,并按照它们出现的顺序进行插入.脚本元素需要在部分加载的DOM的上下文中执行,以便它们仅影响现有的DOM节点.
通过链接元素包含的样式表不会更改DOM(忽略可能通过url插入的javascript).在DOM树解析之前或之后加载样式表都没有关系,因此没有关于资源何时加载的回调.如果使用脚本元素链接到样式表,则在javascript解释器可以决定是否执行任何操作或是否应因异常而崩溃之前,仍然需要加载外部资源.
如果您在隐藏iframe的上下文中预加载每个脚本,则可以将所有错误包含在单独的上下文中,而不会导致页面上运行的javascript崩溃.
请注意:执行功能的外部脚本在删除之前仍然有机会执行.如果脚本正在执行ajax轮询或类似的不必要操作,请考虑不要预加载该特定脚本.
您可能可以使用“已加载”代替“完成”来解决此问题,但是有些较旧的浏览器仅支持onload,因此对于那些浏览器,脚本仍将执行.预加载实际上是用于需要在各种不同页面上调用的库组件的.