当前位置:网站首页>图片懒加载(纯手写)
图片懒加载(纯手写)
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;
}
边栏推荐
猜你喜欢
Talk预告 | 中国科学技术大学和微软亚洲研究院联合培养博士生冷燚冲:语音识别的快速纠错模型FastCorrect
[C] the C language program design, dynamic address book (order)
Doris建表注意事项,实时数仓的同学记得收藏
浅析工业互联网
小程序平台工具如何选择和使用?
There is no recycle bin for deleted files on the computer desktop, what should I do if the deleted files on the desktop cannot be found in the recycle bin?
iNFTnews | In the Web3 era, users will have data autonomy
卷积神经网络CNN详细介绍
ROS Experimental Notes - Install QPEP and Intel-MKL
使用PageHelper自定义PageInfo进行分页+模糊查询
随机推荐
15. 拦截器-HandlerInterceptor
Three-column layout implementation
promise详解
[C Language Chapter] Detailed explanation of bitwise operators (“<<”, “>>”, “&”, “|”, “^”, “~”)
【C语言】初识指针
Pengcheng Cup 2022 web/misc writeup
细谈APP开发焦点问题:AMS 系统时间调节原理
CSDN21天学习挑战赛之折半插入排序
祥云杯 2021 PackageManager writeup
sklearn.datasets.make_circles
HGAME 2022 Final writeup
Promise in detail
ACTF 2022 writeup
高性能MySQL核心整理强势来袭
如何判断一个数为多少进制?
卷积神经网络CNN详细介绍
小程序平台工具如何选择和使用?
Tencent Cloud Lightweight Application Server Configuration and Website Building Tutorial
如果纯做业务测试的话,在测试行业有出路吗?
Unity--URP渲染管线实战教程系列之URP摄像机核心机制剖析