当有人打开了你的网站,而你的网站恰好需要展示很多高质量、精美的图片、日常图片时
一张图片往往都会在500kb-2MB之间,如果有10张图片的话、大约会产生(取中间值1MB)10MB的网络宽带
如果没有使用使用图片懒加载的话,用户打开网站的一瞬间,所有的资源需要全部加载完成才能完整的打开网站
一个网站打开的速度超过5s的话,大部分人都会立刻关闭该网站
其中出现了三个问题
在用户没有看到的地方,就一股脑的加载全部图片
- 这会造成网络资源的浪费
- 增加服务器的压力
- 用户的体验感
这时候就需要使用到图片的懒加载,只有浏览器浏览到的地方才会加载图片,大大节省了网站的响应时间,服务器压力减少
监听scroll滚动事件
用户滚动到的地方,就会加载图片
既然是滚动,很多人都会想到用scroll滚动事件
- 此写法稍微优点复杂COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53/**
* 获取指定代码块的基本信息
* @scrollTop 滚动条纵坐标位置
* @scrollLeft 滚动条横坐标位置
* @param {*} node 元素(标签)
* @returns 当前元素(标签) top|right|bottom|left 距离顶部的距离
*
* nodePos: top|bottom 当前元素在可视区域的上方时获取到的是负数,反之正数
* nodePos: right|left 当前元素距离视区域left的距离,right视区域距离
*
*/
function getNodePosition(node) {
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft,
scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var nodePos = node.getBoundingClientRect(); //获取元素(标签)的参数信息
return {top:nodePos.top + scrollTop, right:nodePos.right + scrollLeft, bottom:nodePos.bottom + scrollTop, left:nodePos.left + scrollLeft }
}
/**
* 图片懒加载
* @selectNode 图片元素(标签)
* @dataImg 图片的真实url地址
*/
function imgLazyLoad(selectNode,dataImg){
// 获取 指定的img
var imgLazyLoad = document.querySelectorAll(selectNode)
var timer,
len = imgLazyLoad.length;
// 加载
function loading(){
timer && clearTimeout(timer); // 清除延迟
timer = setTimeout(function(){ // 设置延迟
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
winHeight = document.documentElement.clientHeight;
// 遍历所有的img
for(var i = 0;i < imgLazyLoad.length;i++){
var nodePos = getNodePosition(imgLazyLoad[i]), // 调用getNodePosition()方法,返回元素的信息
winTop = winHeight+scrollTop;
if((nodePos.top > scrollTop && nodePos.top < winTop) || (nodePos.bottom > scrollTop && nodePos.bottom < winTop)){
imgLazyLoad[i].src = imgLazyLoad[i].getAttribute(dataImg);
}
}
},100);
}
if(!len) return; // 没有img元素则结束
loading();
document.addEventListener('scroll', function(){
if(!len) return;
else loading();
})
}
imgLazyLoad("body img[data-img]","data-img") - 可简写为COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14var body = document.querySelector("body")
var img = document.querySelector("body img[data-img]")
body.addEventListener('scroll',()=>{
img.forEach(img=>{
var imgTop = img.getBoundingClientRect().top
var bodyTop = body.getBoundingClientRect().top
// if(imgTop-bodyTop<=body.clientHeight){
// var src = img.getAttribute("data-img")
// img.setAttribute("src",src)
// }
// 可将上方if压缩为1行
if(imgTop-bodyTop<=body.clientHeight) img.setAttribute("src",img.getAttribute("data-img"))
})
})
IntersectionObserver接口
在写图片懒加载的时候我上Github查找了一下,有个项目https://github.com/tuupola/lazyload使用到了IntersectionObserver接口
,我当时还纳闷,这都没有滚动事件怎么实现的图片懒加载,于是我网上查了IntersectionObserver接口
,发现它的效率比监听scroll
滚动事件快,然后我研究了一下
IntersectionObserver是监听目标元素与其祖先或视窗交叉状态的手段,如果目标元素未定义(为null)的话默认是根据浏览器视图框可见范围
COPY
1 | var io = new IntersectionObserver(callback, options) |
IntersectionObserver
返回一个实例callback
当元素的可见性变化时候触发回调函数options
设置一些配置项(可选)
关于
IntersectionObserver
更多的知识可参考:https://www.jianshu.com/p/84a86e41eb2b
COPY
1 | /** |