You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 实现 ECMA-262, Edition 5, 15.4.4.19// 参考: http://es5.github.com/#x15.4.4.19if(!Array.prototype.map){Array.prototype.map=function(callback,thisArg){varT,A,k;if(this==null){thrownewTypeError(" this is null or not defined");}// 1. 将O赋值为调用map方法的数组.varO=Object(this);// 2.将len赋值为数组O的长度.varlen=O.length>>>0;// 3.如果callback不是函数,则抛出TypeError异常.if(Object.prototype.toString.call(callback)!="[object Function]"){thrownewTypeError(callback+" is not a function");}// 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.if(thisArg){T=thisArg;}// 5. 创建新数组A,长度为原数组O长度lenA=newArray(len);// 6. 将k赋值为0k=0;// 7. 当 k < len 时,执行循环.while(k<len){varkValue,mappedValue;//遍历O,k为原数组索引if(kinO){//kValue为索引k对应的值.kValue=O[k];// 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.mappedValue=callback.call(T,kValue,k,O);// 返回值添加到新数组A中.A[k]=mappedValue;}// k自增1k++;}// 8. 返回新数组AreturnA;};}
Enjoy!!!
The text was updated successfully, but these errors were encountered:
Without jQuery 系列之:lazyload.js
使用原生的js实现简易的图片延时加载。
什么是延时加载?
为什么要使用延时加载?
假如一个网页中,含有大量的图片,当用户访问网页时,那么浏览器会发送n个图片的请求,加载速度会变得缓慢,性能也会下降。如果使用了延时加载,当用户访问页面的时候,只加载首屏中的图片;后续的图片只有在用户滚动时,即将要呈现给用户浏览时再按需加载,这样可以提高页面的加载速度,也提升了用户体验。而且,统一时间内更少的请求也减轻了服务器中的负担。
延时加载的原理
基本原理就是最开始时,所有图片都先放一张占位图片(如灰色背景图),真实的图片地址则放在
data-src
中,这么一来,网页在打开时只会加载一张图片。然后,再给
window
或body
或者是图片主体内容绑定一个滚动监听事件,当图片出现在可视区域内,即滚动距离 + 窗体可视距离 > 图片到容器顶部的距离
时,将讲真实图片地址赋值给图片的 src,否则不加载。使用原生js实现图片的延时加载
延时加载需要传入的参数:
其中:
wrapper
:延时加载的容器。在该容器下,所有符合图片选择器条件的图片均会延时加载。selector
:图片选择器。表示需要延迟加载的图片的选择器,如img.lazyload-image
,默认为所有的 img 标签。imgSrc
:图片真实地址存放属性。表示图片的真实路径存放在标签的哪个属性中,默认为data-src
。defaultSrc
:初始加载的图片地址,默认为空,当为空时,不处理延时加载的图片的路径,若图片本身没有路径,则显示为空。获取容器中所有的图片。
该函数在容器中查找出所有需要延时加载的图片,并将 NodeList 类型的对象转换为允许使用 map 函数的数组。
如果设置了初始图片地址,则加载。
给 window 绑定滚动事件
每次滚动网页时,都会遍历所有的图片,将图片的位置与当前滚动位置作对比,当符合加载条件时,将图片的真实地址赋值给图片,并将图片从集合中移除;当所有需要延时加载的图片都加载完毕后,将滚动事件取消绑定。
测试是否可行
测试结果:
从chrome的网络请求图中可见,5张图片并不是在网页打开的时候就请求了,而是当滑动到某个区域时才触发加载,基本实现了图片的延时加载。
测试结果
性能调整
上述只是简单的实现了一个延时加载的 demo,还有很多地方需要调整和完善。
调整 1:onscroll 函数可能会被覆盖
问题:
因为有时候页面需要滚动无限加载时,插件会重写 window 的 onscroll 函数,从而导致图片的延时加载滚动监听失效。
解决办法:
需要更改为将监听事件注册到 window 上,移除时只需要移除相应的事件即可。
调整后的代码
调整2:滚动时的回调函数执行次数太多
问题
在本次测试中,从动图最后可以看到,当滚动网页时,loadImage 函数执行了非常多次,滚轮每向下滚动 100px 基本上就要执行 10 次左右的 loadImage,若处理函数稍微复杂,响应速度跟不上触发频率,则会造成浏览器的卡顿甚至假死,影响用户体验。
解决办法
使用
throttle
控制触发频率,让浏览器有更多的时间间隔去执行相应操作,减少页面抖动。调整后的代码:
调整后的测试
从动图可见,在滚动的时候,调用判断的回调的次数少了很多。而且也不影响图片的延时加载。
调整后的测试结果
封装为插件形式
上述代码拷贝到项目中即可使用,使用方式:
若在 IE8 中使用,没有 map 函数时,请在引用插件前加入下列处理 map 函数兼容性的代码:
Enjoy!!!
The text was updated successfully, but these errors were encountered: