图片懒加载(节流应用)
2022-03-28 00:00:00

源码

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
54
55
56
57
58
59
60
61
62
63
64
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片懒加载</title>
<style>
.box {
width: 800px;
height: 800px;
border: 1px solid;
overflow: auto;
}

.img {
width: 200px;
height: 200px;
border: 1px solid;
display: block;
margin: 40px auto;
}
</style>
</head>
<body>
<div class="box">
<img class="img" src="https://picsum.photos/200/200" alt="1">
<img class="img" src="https://picsum.photos/200/200" alt="2">
<img class="img" src="https://picsum.photos/200/200" alt="3">
<img class="img" src="https://picsum.photos/200/200" alt="4">
<img class="img" src="" data-src="https://picsum.photos/200/200" alt="5">
<img class="img" src="" data-src="https://picsum.photos/200/200" alt="6">
<img class="img" src="" data-src="https://picsum.photos/200/200" alt="7">
<img class="img" src="" data-src="https://picsum.photos/200/200" alt="8">
<img class="img" src="" data-src="https://picsum.photos/200/200" alt="9">
</div>
</body>
</html>
<script>
var box = document.getElementsByClassName('box')[0];
var imgs = document.getElementsByClassName('img');
box.onscroll = throttle(handleScorllChange);

// 节流函数
function throttle (fn, delay=500) {
let oldTime = Date.now();
return function (...args) {
let newTime = Date.now();
if (newTime - oldTime >= delay) {
fn.apply(null, args);
oldTime = Date.now();
}
}
}
function handleScorllChange () {
let boxHeight = box.clientHeight;
let scrollTop = box.scrollTop;
for (let i = 0; i < imgs.length; i++){
if (imgs[i].offsetTop - 100 < boxHeight + scrollTop && imgs[i].getAttribute('data-src')) {
imgs[i].src = imgs[i].getAttribute('data-src')
}
}
}
</script>

解析

监听图片容器元素的滚动事件,通过每张图片的 offsetTop(距离父元素顶部的距离)判断图片是否即将显示,即将显示时给 src 赋值。

  • html 部分

    通过 picsum.photos 生成图片,初次加载时显示的图片直接设置 src

  • js 部分

    图片容器元素添加滚动监听事件,会高频触发影响浏览器性能,故使用节流算法,节流请看节流与防抖

    1
    2
    3
    var box = document.getElementsByClassName("box")[0];
    var imgs = document.getElementsByClassName("img");
    box.onscroll = throttle(handleScorllChange);

    监听事件:循环图片元素,判断图片元素是否“ 即将出现 ”,即 图片距父元素顶部的距离 < 容器高度 + 已经滚过的距离,这里“ -100 ”是为了预留足够的加载时间使图片再提前一些加载。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function handleScorllChange() {
    let boxHeight = box.clientHeight;
    let scrollTop = box.scrollTop;
    for (let i = 0; i < imgs.length; i++) {
    if (
    imgs[i].offsetTop - 100 < boxHeight + scrollTop &&
    imgs[i].getAttribute("data-src")
    ) {
    imgs[i].src = imgs[i].getAttribute("data-src");
    }
    }
    }
Prev
2022-03-28 00:00:00