根据请求的数据动态懒加载图片

本文介绍了一种实现图片懒加载的方法。首先通过加载loading图片作为占位符,然后获取后台数据并替换为带有loading的div。利用JavaScript的offsetTop、clientHeight和pageYoffset等API,在图片进入可视窗口时开始加载,从而优化页面性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

思考:假如给你50+张图片,你如何实现懒加载?

思路:
  1. 加载loading图片:先在显示9张带着loading图片的div块进行占位
  2. 获取后台数据,根据请求图片数量替换并生成同等数量的带着loading的div块
  3. 利用Image()对象先将图片加载至内存,
  4. 待加载完毕再将图片替换loading.png;
知识预热:

利用图片到 浏览器顶部的距离offsetTop的距离=浏览器可视窗口的距离clientHeight+滚动条距离scrollHeight 的时候开始加载图片。

可视窗口获取api:
  • 原生方法:window.innerHeight 标准浏览器及IE9+
  • document.documentElement.clientHeight 标准浏览器及低版本IE标准模式
  • document.body.clientHeight 低版本混杂模式
  • jQuery方法: $(window).height()
滚动条获取api:
  • 原生方法:window.pageYoffset——IE9+及标准浏览器
  • document.documentElement.scrollTop 兼容ie低版本的标准模式
  • document.body.scrollTop 兼容混杂模式;
  • jQuery方法:$(document).scrollTop();
获取元素本身的位置信息:
  • 原生:ele.offsetTop获取ele距离顶部的距离,距 offsetParent 元素的顶部内边距的距离。
  • jQuery:(o).offset().top元素距离文档顶的距离。

整体实现

json数据和项目结构
在这里插入图片描述

  • 在这,我用fetch进行异步请求数据。然后进行div块渲染。
  • 数据请求后直接执行 判断图片是否在可视 界面 ;执行fn();
  • 对window添加监听函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i2h4P9RO-1595837497692)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20200727160631822.png)]

代码:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片懒加载</title>
    <style>
        html,
        body {
            padding: 0;
            margin: 0;
        }

        .container {
            padding: 10px;
            background-color: darkkhaki;
            width: 100%;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: center;
        }

        .item {
            border: 1px solid darkgray;
            background-color: white;
            margin: 10px;
            padding: 10px;
            width: 400px;
            height: 400px;
            text-align: center;
            line-height: 400px;
        }

        .item img {
            width: 50px;
            height: 50px;
        }

        .item img.over {
            width: 400px;
            height: 400px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
        <div class="item"><img src="./img/loading.gif"></div>
    </div>
</body>
<script>

    let divItem = document.querySelector('.container'),
        str = '';
	//fetch进行异步请求
    fetch('./data.json').then(res => {
        return res.json();
    }).then(res => {
        let url = res;
        for (let i = 0; i < url.length; i++) {
            str += `<div class="item"><img src="./img/loading.gif" data-src=${url[i]}></div>`;
        }
		//本来想法是向末尾添加元素
        // divItem.insertAdjacentHTML('beforeend', str);
        divItem.innerHTML = str;

        let imgs = document.querySelectorAll('img');
		// 获取元素距离顶部距离
        function getTop(o) {
            let T = o.offsetTop;
            return T;
        }
        //判断图片是否应该渲染
        function fn() {
            //可视高度
            let clientHeight = window.innerHeight || document.documentElement.clientHeight;
            // 滚动条距离
            let scrollHeight = pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
            for (let i = 0; i < imgs.length; i++) {
                if (clientHeight + scrollHeight > getTop(imgs[i])) {
                    // 设置延时,形成异步加载效果
                    setTimeout(() => {
                    // 创建一个临时图片,这个图片在内存中不会到页面上去。实现隐形加载;在内存中加载完毕再渲染
                    let temp = new Image();
                    temp.src = imgs[i].getAttribute('data-src');
                    temp.onload = function () {
                        //在内存中加载完毕,替换真图片
                        imgs[i].className = 'over';
                        imgs[i].src = imgs[i].getAttribute('data-src');
                    }
                    }, 1500)
                }
            }
            // 全部加载完毕后,去掉监听事件
            if (document.querySelectorAll('.over').length == imgs.length) {
                window.removeEventListener('scroll', fn, false);
            }
        }
		请求回来后,直接执行,进行可视界面的图片加载。
        fn();
        window.addEventListener('scroll', fn, false);
    });



</script>

</html>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值