图片懒加载

在项目开发中,页面存在大量的图片,如果把图片都全部加载出来,此时页面加载可能会出现卡顿灯情况,对用户来说,流量耗费也是很大的,此时,对页面图片作懒加载处理是很有必要的。

在项目开发中,页面存在大量的图片,如果把图片都全部加载出来,此时页面加载可能会出现卡顿灯情况,对用户来说,流量耗费也是很大的,此时,对页面图片作懒加载处理是很有必要的。

懒加载的目的

在页面需要的时候才发送请求去加载资源,不需要的时候就不加载,这样可以减少请求,节约资源。

当img标签中有src属性时都会发送请求,所以通常在做图片懒加载时先不设置src属性,后面通过js添加该属性,来显示要显示的内容

懒加载的大概原理

  1. img标签不设置src属性
  2. 监听浏览器可视区域,图片若出现在可是区域内,则加载、显示图片

主要实现代码

判断元素是否在可视区域

方法一:

  1. 通过document.documentElement.clientHeight获取屏幕可视窗口高度
  2. 通过element.offsetTop获取元素相对于文档顶部的距离
  3. 通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
  4. 判断②-③ 与①的大小
    1
    2
    3
    4
    5
    6
    7
    function isInsight(el){
    let viewsHei = document.documentElement.clientHeight;
    let offsetTop = el.offsetTop;
    let scrollTop = document.documentElement.scrollTop

    return offsetTop - scllTop < viewsHei
    }
    方法二:

    通过getBoundingClientRect()方法来获取元素的大小以及位置,该方法返回一个名为ClientRect的DOMRect对象,包含了top、right、botton、left、width、height这些值。该方法的兼容性:请点这里

1
2
3
4
5
6
7
function isInSight(el) {
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
//如果只考虑向下滚动加载
//const clientWidth = window.innerWeight;
return bound.top <= clientHeight + 100;
}
加载图片

页面打开时需要对所有图片进行检查,是否在可视区域内,如果是就加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let isShowIndex = 0; //标记图片是否已经加载
function checkImgs() {
const imgs = document.querySelectorAll('img');
for(let i = isShowIndex;i<imgs.length;i<++){
if (isInSight(imgs[i]){
loadImgs(imgs[i])
}
}

<!--Array.from(imgs).forEach(el => {
if (isInSight(el)) {
loadImg(el);
}
})-->
}

function loadImg(el) {
if (!el.src) {
const source = el.dataset.src;
el.src = source;
}
isShowIndex++
}

完整代码

html部分
1
2
3
4
5
6
<img data-src="image/js.jpg"  alt="">
<img data-src="image/js.jpg" alt="">
<img data-src="image/js.jpg" alt="">
<img data-src="image/js.jpg" alt="">
<img data-src="image/js.jpg" alt="">

js部分
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
window.onload = window.onscroll = function () {
function isInSight(el) {
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
//如果只考虑向下滚动加载
//const clientWidth = window.innerWeight;
return bound.top <= clientHeight + 100;
}
let isShowIndex = 0; //标记图片是否已经加载
function checkImgs() {
const imgs = document.querySelectorAll('img');
for(let i = isShowIndex;i<imgs.length;i++){
if (isInSight(imgs[i])){
loadImg(imgs[i])
}
}
}

function loadImg(el) {
if (!el.src) {
const source = el.dataset.src;
el.src = source;
}
isShowIndex++
console.log(isShowIndex)
}
checkImgs()
}

这样就实现了一个简易的图片的懒加载

由于页面滚动事件是一个高频触发的事件,需要作相应处理,使被执行函数不会被频繁执行