当前位置:网站首页>图片懒加载(纯手写)
图片懒加载(纯手写)
2022-08-10 23:36:00 【朝阳39】
什么是图片懒加载?
默认情况下不加载图片,直到滚动页面,图片进入浏览器窗口的可视区域,才加载图片!
图片懒加载效果预览

图片懒加载实现原理
图片默认的src属性为空,图片地址存放在data-src属性中,当图片进入可视区域,从data-src属性中取得图片地址,赋值给src属性完成图片的加载
图片懒加载的实现方案
- 全局监听浏览器滚动事件
- 滚动事件中判断是否有图片进入可视区域
- 若图片进入可视区域,则加载图片
- 加载图片的过程为:从data-src属性中取得图片地址,赋值给src属性
图片懒加载的完整范例代码
目录结构
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div style="height: 1000px">
<img src="./images/1.jpg" />
</div>
<div>
<img class="lazy-element" data-src="./images/2.jpg" />
</div>
<div>
<img class="lazy-element" data-src="./images/3.jpg" />
</div>
<div>
<img class="lazy-element" data-src="./images/4.jpg" />
</div>
<script type="text/javascript" src="./lazy.js"></script>
</body>
</html>
lazy.js
/* 图片懒加载的原理: 图片默认的src属性为空,图片地址存放在data-src属性中 >> 当图片进入可视区域 - 从data-src属性中取得图片地址,赋值给src属性完成图片的加载 图片懒加载的实现方案: 1. 全局监听浏览器滚动事件 2. 滚动事件中判断是否有图片进入可视区域 3. 若图片进入可视区域,则加载图片 4. 加载图片的过程为:从data-src属性中取得图片地址,赋值给src属性 */
// 设定懒加载元素的样式名为 lazy-element
let lazyElementClassName = "lazy-element";
// 设定存储图片地址的属性为 data-src
let srcAttrName = "data-src";
// 定义变量--存储浏览器窗口的高度;
let _viewportHeight;
// 定义变量--存储浏览器窗口与页面顶部的距离;
let _pageYOffset;
// 更新浏览器窗口的高度
function setViewportHeight() {
_viewportHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
}
// 更新浏览器窗口与页面顶部的距离
function setPageYOffset() {
_pageYOffset =
window.pageYOffset ||
window.scrollY ||
document.documentElement.scrollTop ||
document.body.scrollTop;
}
// 通过 getElementsByClassName 获取所有懒加载元素(数据类型为类似数组的HTMLCollection)
// 使用Array.prototype.slice.call方法将HTMLCollection转化为数组
let elements = Array.prototype.slice.call(
document.getElementsByClassName(lazyElementClassName)
);
// 设定一个标记 —— 页面是否滚动(默认未滚动)
let initialized = false;
// 初始化浏览器窗口的高度
setViewportHeight();
// 全局监听浏览器滚动事件
window.onscroll = function () {
// 浏览器滚动时,触发懒加载图片的检测
scrollEventHandler();
// 页面滚动时,更新浏览器窗口与页面顶部的距离
setPageYOffset();
};
// 全局监听浏览器窗口大小改变事件
window.onresize = function () {
// 浏览器窗口大小改变时,更新浏览器窗口的高度
setViewportHeight();
};
function scrollEventHandler() {
// 页面滚动时
if (!initialized) {
requestAnimationFrame(function update() {
// 判断是否加载图片
checkAvailable();
// requestAnimationFrame 的回调函数只会被调用一次,如果希望每帧都执行,则每帧都需要调用
requestAnimationFrame(update);
});
}
// 滚动过后,标记为页面已滚动
initialized = true;
}
// 判断是否加载图片
function checkAvailable() {
for (let i = 0; i < elements.length; i++) {
let el = elements[i];
// 一旦检测发现进入可视区域
if (checkElementIsInViewport(el)) {
// 则加载图片
loadElement(el);
// 并将该元素踢出队列
elements.splice(i--, 1);
}
}
}
// 判断元素是否进入可视区域
function checkElementIsInViewport(elem) {
if (elem.getBoundingClientRect) {
// getBoundingClientRect方法用于获取元素相对于视口左上方的位移;
let elemPos = elem.getBoundingClientRect();
// 元素与视口顶部的距离小于或等于视口高度时,元素进入可视区域
if (elemPos.top && elemPos.top > 0 && elemPos.top <= _viewportHeight) {
return true;
}
return false;
} else {
// 兼容不支持getBoundingClientRect的浏览器
let offsetTop = getElemOffsetTop(elem);
// 元素与页面顶部的距离小于或等于视口高度+视口顶部与页面顶部的距离时,元素进入可视区域
if (
offsetTop > _pageYOffset &&
offsetTop < _pageYOffset + _viewportHeight
) {
return true;
}
return false;
}
}
// 获取元素与页面顶部的距离
function getElemOffsetTop(el) {
let top = el.offsetTop;
let parent = el.offsetParent;
while (parent) {
top += parent.offsetTop || 0;
parent = parent.offsetParent;
}
return top;
}
// 加载图片: 从data-src属性中取得图片地址,赋值给src属性
function loadElement(elem) {
let srcURL = elem.getAttribute(srcAttrName);
elem.src = srcURL;
}
边栏推荐
猜你喜欢
![[C Language Chapter] Detailed explanation of bitwise operators (“<<”, “>>”, “&”, “|”, “^”, “~”)](/img/7a/4c4e74a294074e1f5fc573d21adb20.png)
[C Language Chapter] Detailed explanation of bitwise operators (“<<”, “>>”, “&”, “|”, “^”, “~”)

生态伙伴开发实践 | 智慧检测实验室应用系统快速接入指令集数字底座

sqlmap结合dnslog快速注入

62.【彻底改变你对C语言指针的厌恶(超详细)】

Geogebra 教程之 02 Geogebra初学者的 8 个基本要素

SQL注入基础---order by \ limit \ 宽字节注入

阿里P7晒出1月工资单:狠补了这个,真香...

App的回归测试,有什么高效的测试方法?

C3604环保黄铜带

【C语言】C语言程序设计:动态通讯录(顺序表实现)
随机推荐
基于Web的疫情隔离区订餐系统
SQL注入基础---order by \ limit \ 宽字节注入
安科瑞为工业能效行动计划提供EMS解决方案-Susie 周
HGAME 2022 Week3 writeup
DASCTF 2022 7月赋能赛 writeup
编程语言为什么有变量类型这个概念?
62.【彻底改变你对C语言指针的厌恶(超详细)】
sklearn.datasets.make_circles
C3604环保黄铜带
How to quickly grasp industry opportunities and introduce new ones more efficiently is an important proposition
mysql索引,事务与存储引擎
Pengcheng Cup 2022 web/misc writeup
Cache knowledge summary
VR全景+安全科普教育,让学生们提高安全意识
22年全国程序员1月薪资出炉,才知道年薪 40 万以上的有这么多?
CW614N铜棒CuZn39Pb3对应牌号
电脑桌面删除的文件回收站没有,电脑上桌面删除文件在回收站找不到怎么办
Activiti7子流程之Call activity
一条SQL查询语句是如何执行的?
CSDN21天学习挑战赛之折半插入排序