原生JavaScript实现图片懒加载

什么是图片懒加载

我们有一个页面,展示图片列表的,图片很多多到当前屏幕展示不下。懒加载就是加载可视区域内的图片。一般图片我们是使用 <img> 标签来实现的,浏览器根据标签上的 src 属性来发起获取图片的请求。我们在未进入到可视区域内,先不给 <img> 标签添加 src 属性,这样动态的控制标签 src 属性就可以完成懒加载了。

示例

1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
    <title>图片懒加载</title>
8
    <style>
9
        .list{
10
            margin: 0 auto;
11
            width: 500px;
12
        }
13
14
        .images{
15
            width: 100%;
16
            height: 100%;
17
        }
18
19
        .images img{
20
            width: 500px;
21
            height: 300px;
22
        }
23
    </style>
24
</head>
25
<body>
26
    <div class="list">
27
        <div class="images">
28
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3681880960,455182084&fm=26&gp=0.jpg">
29
            <img data-src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3721400011,1403299293&fm=26&gp=0.jpg" alt="">
30
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1920661160,3332292898&fm=26&gp=0.jpg" alt="">
31
            <img data-src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3780377048,403990503&fm=26&gp=0.jpg" alt="">
32
            <img data-src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=389790139,3572772338&fm=26&gp=0.jpg" alt="">
33
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=21597997,2581227973&fm=26&gp=0.jpg" alt="">
34
            <img data-src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3744811142,1586661297&fm=26&gp=0.jpg" alt="">
35
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3681880960,455182084&fm=26&gp=0.jpg">
36
            <img data-src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3721400011,1403299293&fm=26&gp=0.jpg" alt="">
37
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1920661160,3332292898&fm=26&gp=0.jpg" alt="">
38
            <img data-src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3780377048,403990503&fm=26&gp=0.jpg" alt="">
39
            <img data-src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=389790139,3572772338&fm=26&gp=0.jpg" alt="">
40
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=21597997,2581227973&fm=26&gp=0.jpg" alt="">
41
            <img data-src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3744811142,1586661297&fm=26&gp=0.jpg" alt="">
42
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3681880960,455182084&fm=26&gp=0.jpg">
43
            <img data-src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3721400011,1403299293&fm=26&gp=0.jpg" alt="">
44
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1920661160,3332292898&fm=26&gp=0.jpg" alt="">
45
            <img data-src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3780377048,403990503&fm=26&gp=0.jpg" alt="">
46
            <img data-src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=389790139,3572772338&fm=26&gp=0.jpg" alt="">
47
            <img data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=21597997,2581227973&fm=26&gp=0.jpg" alt="">
48
            <img data-src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3744811142,1586661297&fm=26&gp=0.jpg" alt="">
49
        </div>
50
    </div>
51
    <script src="./index.js"></script>
52
</body>
53
</html>
1
let images = document.querySelectorAll('img');
2
let number = images.length;
3
let index = 0;      // 存储图片加载到的位置,避免没吃都从第一张图片开始遍历
4
let clientHeight = gelCientHeight();  //屏幕可视区域的高度
5
let scrollTop = getScrollTop();   // 滚动条距离顶部高度
6
let isLoadImage = false;        // 当前容器内的图片是否加载完成
7
8
function lazyload(){
9
    isLoadImage = index >= number;
10
    scrollTop = getScrollTop();
11
    for (let i = 0; i < number; i++) {
12
        // images[i].offsetTop = element.offsetTop   获取元素相对于文档顶部的高度
13
        if (images[i].offsetTop < clientHeight + scrollTop){
14
            console.log(images[i].getAttribute('src'));
15
            if(!images[i].getAttribute('src')){
16
                images[i].src = images[i].getAttribute('data-src')
17
            }
18
            index = i + 1;
19
        }
20
        
21
    }
22
}
23
24
// 获取滚动条距离顶部高度
25
function getScrollTop (){
26
    return document.documentElement.scrollTop || document.body.scrollTop;
27
}
28
29
// 获取屏幕可视区域的高度
30
function gelCientHeight(){
31
    return document.documentElement.clientHeight
32
}
33
34
// 重新计算可见区域高度
35
function computedClientHeight(){
36
    clientHeight = gelCientHeight();
37
    console.log(clientHeight);
38
}
39
40
lazyload();
41
42
43
const debounce = (fn, interval = 300) => {
44
    let timer = null;
45
    return function () {
46
        clearTimeout(timer);
47
        timer = setTimeout(() => {
48
            fn.apply(this, arguments);
49
        }, interval);
50
    }
51
}
52
53
const throttle = (fn, interval = 300) => {
54
    let run = true;
55
    return function () {
56
        if (!run) return;
57
        run = false;
58
        setTimeout(() => {
59
            fn.apply(this, arguments);
60
            run = true;
61
        }, interval);
62
    };
63
}
64
65
window.addEventListener('scroll',throttle(lazyload),100)
66
67
window.addEventListener('resize', debounce(computedClientHeight,500))