能不能实现图片懒加载?

news/2025/3/9 22:51:12/文章来源:https://www.cnblogs.com/cdyun/p/18612973

方案一:clientHeight、scrollTop 和 offsetTop

首先给图片一个占位资源:

<img src="default.jpg" data-src="http://www.xxx.com/target.jpg" />

接着,通过监听 scroll 事件来判断图片是否到达视口:

let img = document.getElementsByTagName("img");
let num = img.length;
let count = 0;//计数器,从第一张图片开始计lazyload();//首次加载别忘了显示图片window.addEventListener('scroll', lazyload);function lazyload() {let viewHeight = document.documentElement.clientHeight;//视口高度let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//滚动条卷去的高度for(let i = count; i <num; i++) {// 元素现在已经出现在视口中if(img[i].offsetTop < scrollHeight + viewHeight) {if(img[i].getAttribute("src") !== "default.jpg") continue;img[i].src = img[i].getAttribute("data-src");count ++;}}
}

当然,最好对 scroll 事件做节流处理,以免频繁触发:

// throttle函数我们上节已经实现
window.addEventListener('scroll', throttle(lazyload, 200));

方案二:getBoundingClientRect

现在我们用另外一种方式来判断图片是否出现在了当前视口, 即 DOM 元素的 getBoundingClientRect API。

上述的 lazyload 函数改成下面这样:

function lazyload() {for(let i = count; i <num; i++) {// 元素现在已经出现在视口中if(img[i].getBoundingClientRect().top < document.documentElement.clientHeight) {if(img[i].getAttribute("src") !== "default.jpg") continue;img[i].src = img[i].getAttribute("data-src");count ++;}}
}

方案三: IntersectionObserver

这是浏览器内置的一个API,实现了监听window的scroll事件判断是否在视口中以及节流三大功能。

我们来具体试一把:

let img = document.getElementsByTagName("img");const observer = new IntersectionObserver(changes => {//changes 是被观察的元素集合for(let i = 0, len = changes.length; i < len; i++) {let change = changes[i];// 通过这个属性判断是否在视口中if(change.isIntersecting) {const imgElement = change.target;imgElement.src = imgElement.getAttribute("data-src");observer.unobserve(imgElement);}}
})
Array.from(img).forEach(item => observer.observe(item));

这样就很方便地实现了图片懒加载,当然这个IntersectionObserver也可以用作其他资源的预加载,功能非常强大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854408.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UOS给deb包签名

跳过打包过程,主要记录签名1.在应用商城下载 “证书工具” 2. 打开一个终端,生成证书// 如果没有账号,就去注册一个就可以了,UOS官网:https://www.chinauos.com cert-tool -username="UOS帐号" -password="UOS密码" 3. 对打包好的deb安装包做签名,签…

零基础学习人工智能—Python—Pytorch学习(十三)

前言 最近学习了一新概念,叫科学发现和科技发明,科学发现是高于科技发明的,而这个说法我觉得还是挺有道理的,我们总说中国的科技不如欧美,但我们实际感觉上,不论建筑,硬件还是软件,理论,我们都已经高于欧美了,那为什么还说我们不如欧美呢? 科学发现是高于科技发明就…

使用Flink实现MySQL实时同步数据到StarRocks(库表级)

这里引用官网的文章 + 我在使用时遇到的问题。官网已经讲解的很明白了。 从MySQL实时同步 StarRocks 支持多种方式将 MySQL 的数据实时同步至 StarRocks,支撑实时分析和处理海量数据的需求。 本文介绍如何将 MySQL 的数据通过 Apache Flink 实时(秒级)同步至 StarRocks。注意…

2012/12/17 遗传算法求解混合流水车间调度问题的相关内容包括demo实现, 知识点:VS code的快捷键操作

遗传算法求解混合流水车间调度问题(附C++代码)VS code的快捷键操作: 1.快速查看函数定义,以及返回跳转前的位置 Vscode快捷键_vscode 转到实现方法-CSDN博客 2.VS code如何同时多行缩进 Shift + Tab

visual C++ 编译环境下载安装

https://my.visualstudio.com/Downloads这个安装包比较小, 不要装一个臃肿的visual studio本文来自博客园,作者:那时一个人,转载请注明原文链接:https://www.cnblogs.com/qianxunman/p/18612827

SMBJ18A-ASEMI瞬态抑制二极管SMBJ18A

SMBJ18A-ASEMI瞬态抑制二极管SMBJ18A编辑:ll SMBJ18A-ASEMI瞬态抑制二极管SMBJ18A 型号:SMBJ18A 品牌:ASEMI 封装:SMB 批号:最新 引脚数量:2 安装类型:表面贴装型 电流:18A 功率:600W 工作温度:-65C~+150C SMBJ18A应用领域 SMBJ18A可用于计算机系统:在计算机系统中,瞬…

声音

音乐 音效 摄像机听声音 对象(物体)播放声音 脚本控制音乐播放 键盘控制音乐播放及音效播放

SQL Server数据库数据的导入与导出

不同数据库之间导数据 flowchart LR 右键单击需要导数据的数据库--点击-->任务--点击-->导出数据点击下一步选择数据源 Microsoft OLE DB Provider for SQL Serverflowchart LR 选择好数据源-->设置服务器名称-->选择使用SQLServer身份验证-->输入用户名和密码-…

gown和robe的区别

中文词典总是把gown和robe翻译成“礼袍”或者“长袍”。这样虽然不算错,但是非常误导人。 通常,gown指的是晚礼服。比如中国婚礼上新娘穿的拖地的裙子。而robe则一般指睡衣。这两个东西可以说是八竿子打不着的东西。gownrobe 之所以词典总是翻译成礼袍或者长袍,是因为robe可…

一文读懂光纤以太网IEEE 802.3cz-上

应用于工业领域的光通信技术因其高带宽、长距离、低电磁干扰的特点得到了密切的关注,IEEE在2023年发布了802.3cz协议,旨在定义一套光纤以太网在车载领域的应用标准。 随着对车载高速总线的深入研究,以电信号为媒介的传输方式逐渐显露出劣势,当传输速率超过25Gbps时,…

vue3中配置svg

整体目标实现一个在 Vue 项目中方便使用 SVG 图标,允许在页面中通过自定义标签直接引用 SVG 图标,无需手动引入每个图标文件。具体步骤1. 使用方式 页面中直接写标签,myicon是svg图片文件名,不需要引入。myicon文件放在指定的svg目录中即可。<svg-icon icon-class="…

线性电源 单电源供电 正负双路输出 万分之一纹波 高转换效率 输入3~40V,输出线性电压2.5~32V 可调

线性电源 单电源供电 正负双路输出 万分之一纹波 高转换效率 输入3~40V,输出线性电压2.5~32V 可调低纹波双路可调线性电源 宽电压输入输出高转换效率 BSN30WL是一款宽电压输入的升降压、正负电压线性电源。它具有多种应用场景,例如用于精密运放的正负电源、模数和数模转换的供…