为了提高用户体验,在做一些比较多资源的项目,我们经常会用资源预加载的方式,一打开页面会先看到一个loading动画效果或者loading进度条,再或者加载百分比,用来暗示用户,页面资源比较多,正在加载中啦,你再等等哈,不要走喔。。。
而这里的资源预加载,就是通过js去预先请求某些资源,以备页面展示时可以直接使用,比如图片预加载,我们可能会这样实现:
1 | var img = new Image(); |
通过创建一个不可见的img来触发图片请求,上面演示的只是加载一张,一般情况做预加载都会有多资源才做啦,所以批量预加载只需要加入循环:
1 | var iFileData = [//预加载图片资源 |
上面可以实现简单的预加载了,但好像没有当前加载的进度喔
下面加上一个当前加载进度的百分比:
1 | checkLoadComplete = function(){ |
到这,资源预加载的功能基本就ok了,然后展示进度跟进上面的进度返回,转成数字百分比或者一个进度条就可以了。
另外,这个功能很常用,可以再做一下封装,方便使用,还可以加入其它资源的支持,比如多媒体文件?
完了?
但,这个不是本文的重点,本文的重点是线性
。
改良,让加载更线性
上面的预加载有个问题,体验不好。比如,你要预加载10个资源,显示的百分比就是0%,10%,20%,30%…这样10个数字的跳动,极端点,当你只有一个资源(当然这里是极端考虑,像前文说的,一个资源,你估计不会用预加载了)时,进度就是0%~100%,一下就从0跳到100了。
还有,即使是10个资源,当用户第二次打开页面,因为资源有缓存,这个loading效果就会可能一闪而过,因为有缓存加载太快了,进度都看不清就没了,体验也不好(或者即使第一次,如果用户网速很好,也会出现一闪而过)。
所以,上面的预加载体验不够好,不稳定,导致动画效果不线性。
预想的线性是怎样的呢?比如进度百分比数字,我预想的是无论多少资源,第几次打开,网速如何,都是从0%,1%,2%,3%,4%,5%,6%….这样直到100的,只有这样,数字展示才不会大幅度跳动或者进度条的宽度才不会跳跃。
那怎么达到这样的数字累加效果呢?咦?累加?那可以用定时器啊:
1 | var _num = 0; |
嗯,这样数字就不跳动啦,很线性!!从0100,每隔50毫秒加1,到100就停止,so easy
线性数字有了,但和我加载进度有毛关系?而且资源加载是会根据网速不同而不同,这50毫秒。。。假的进度,明显不行啊
第一个问题,线性数字和实际资源加载联系起来,这个还是很容易的。从第一个资源开始,就同时触发触发上面的计时器,当最后一个资源加载完而且计算到100了,就完成了预加载过程。
第二个问题,定时器的时间怎么和实际资源加载联系起来呢?定时器先根据资源数定一个初始值,加载过程通过把假的计算进度和真实的加载进度进行比较,实时调整定时器的时间,以达到尽可能的模拟实际进度:
1 | var _time = 50; |
逻辑细节请移步测试demo:http://www.w3cmark.com/staticdemo/loading/