当咱们碰到长网页有不少图片时,咱们会采用先加载出如今视口内的几张图片,当滚动条滚动到相应图片的位置时才去加载别的图片。这种延迟加载的方式咱们就称之为懒加载。html
假设一个场景:当咱们浏览淘宝的时候,页面须要加载很长时间才能显示出来,根据3秒钟定律,此时用户确定已经失去了耐心。可是使用懒加载就可以大大提高页面的展示速度,从而提高用户体验。git
想象一下,若是一我的须要在短期内作不少事情,那这我的确定压力会很大。服务器也是同样的,咱们经过懒加载就减轻了服务器的工做量,让它有时间缓一缓,再来处理后面的事情。github
前面铺垫了这么多,下面重点来了(敲黑板!!!)。api
clientHeight
:浏览器视口的高度;scrollTop
:滚动轴滚动的距离;offsetTop
:图片的头部距离浏览器顶部的高度(注意不是距离视口顶部的高度);咱们实现懒加载的想法是一开始只加载显示在视口内的图片,从上图能够看出,咱们能够先只加载前两张图片。那么如何保证图片不加载出来呢?浏览器
能够经过将图片的地址保存在
img
元素的自定义属性上面,当须要加载的时候再将该自定义属性赋值给该图片的src
。性能优化
那么问题来了,何时加载后面的图片呢?bash
就是在咱们滚动滚动轴的时候,当下一张图片的顶部立刻要出如今视口的时候去加载下一张图片。服务器
好啦,如今咱们已经知道该什么去加载下一张图片了。那么接下来是第二个问题:怎么知道下一张图片立刻要出如今视口上了呢?dom
就是当图片距离浏览器顶部的高度---即
offsetTop
<=
视口高度clientHeight
+ 滚动条的长度scrollTop
。这是重点!!!明白了这个后面就简单了函数
最后一个问题,如何获取offsetTop
、scrollTop
、clientHeight
这三个数值呢?
offsetTop
:直接经过img.offsetTop
就能够获取;scrollTop
:经过document.documentElement.scrollTop
获取;clientHeight
:经过document.documentElement.clientHeight
获取;
此处主要介绍懒加载,对于上述三个api
不熟悉可自行百度学习。建议先记住他们能够这么获取就行。
html
结构和CSS
样式;<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img {
height: 450px;
display: block;
margin-bottom: 20px;
}
</style>
</head>
<body>
<!--图片地址暂时先保存在data-src这个自定义属性上面-->
<img data-src="./img-loop/img/1.jpg" alt="懒加载1" />
<img data-src="./img-loop/img/2.png" alt="懒加载2" />
<img data-src="./img-loop/img/3.jpg" alt="懒加载3" />
<img data-src="./img-loop/img/4.jpg" alt="懒加载4" />
<img data-src="./img-loop/img/5.jpg" alt="懒加载5" />
</body>
</html>
复制代码
js
;const imgs = document.getElementsByTagName('img');
function lazyLoad(imgs) {
// 视口的高度;
const clientH = document.documentElement.clientHeight;
// 滚动的距离,这里的逻辑判断是为了作兼容性处理;
const clientT = document.documentElement.scrollTop || document.body.scrollTop;
for(let i = 0; i < imgs.length; i++) {
// 逻辑判断,若是视口高度+滚动距离 > 图片到浏览器顶部的距离就去加载;
// !imgs[i].src 是避免重复请求,能够把该条件取消试试:能够看到不加该条件的话往回滚动就会重复请求;
if(clientH + clientT > imgs[i].offsetTop && !imgs[i].src) {
// 使用data-xx的自定义属性能够经过dom元素的dataset.xx取得;
imgs[i].src = imgs[i].dataset.src;
}
}
};
// 一开始可以加载显示在视口中的图片;
lazyLoad(imgs);
// 监听滚动事件,加载后面的图片;
window.onscroll = () => lazyLoad(imgs);
复制代码
至此,咱们就完成了开头gif图的懒加载的效果。
其实上面的代码仍是有不少性能优化的地方,好比说对于频繁触发的
scroll
事件会给浏览器形成很大的压力。咱们可使用节流函数作一个优化;
lazyLoad
函数频繁触发;// 设置节流函数
function throttle(fn, delay) {
let timer = null;
return () => {
if(timer) {
return;
};
timer = setTimeout(() => {
fn(imgs);
timer = null;
}, delay)
}
}
// 监听滚动事件,加载后面的图片;
window.onscroll = throttle(lazyLoad, 500);
复制代码