图片懒加载
前端
0
549
0
发表于: 2020-08-21 22:07:13
简介: 暂无~
图片懒加载
场景
一个网页会包含很多的图片,例如淘宝京东这些购物网站,商品图片很多,如果在首页就全部加载的话,会影响渲染速度(比如出现白屏)和浪费带宽,为了解决以上问题,提高用户体验,就出现了懒加载方式来减轻服务器的压力,优先加载可视区域的内容,其他部分等进入了可视区域再加载,从而提高性能。
原理
一张图片就是一个img标签,浏览器是否发起请求图片是根据img的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给img的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。
实现
- 加载loading图片进行占位
- 判断哪些图片要加载
- 将loading图片替换真图片
html结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<img
data-src="https://resource.hsslive.cn/image/1578937683585vueblog.webp"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
<img
data-src="https://resource.hsslive.cn/image/1582634581438regexr.webp"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
<img
data-src="https://resource.hsslive.cn/image/1582472959525git.webp"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
<img
data-src="https://resource.hsslive.cn/image/1582618699043array.webp"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
<img
data-src="https://resource.hsslive.cn/image/1638093406012author.webp"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
<img
data-src="https://resource.hsslive.cn/image/1662362144932__7TCL__sdd.png"
src="https://resource.hsslive.cn/image/f926bacffc39fc496f22ca13a68c3062.jpg"
alt="加载中..."
width="300"
height="300" />
</body>
</html>
计算offsetTop实现
缺点:offsetTop是计算距离的父级的元素的值,不是计算相对屏幕的值!
console.log('计算offsetTop实现');
// 懒加载
function lazy() {
// 获取页面滚动条卷去的高度
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
// 获取页面高度
let windowHeight =
window.innerHeight || document.documentElement.clientHeight;
// 获取所有img标签
var imgs = document.querySelectorAll('img');
for (let i = 0; i < imgs.length; i++) {
// 获取每个img标签距离body的高度
let imgOffsetTop = imgs[i].offsetTop;
console.log(imgOffsetTop, scrollTop);
/**
* 1.如果img标签距离body的高度小于(页面高度+被卷去的高度),则代表当前img标签在可视区域,则加载图片
* 2.由于如果从最底部加载的话,最开头的图片一定符合上面的条件,
* 因此要判断img标签距离body的高度有没有大于滚动的高度,大于滚动高度了才加载图片
*/
if (imgOffsetTop < windowHeight + scrollTop && imgOffsetTop >= scrollTop) {
const imgSrc = imgs[i].getAttribute('data-src');
// 如果有data-src属性,将它的值赋给src
if (imgSrc) {
imgs[i].src = imgSrc;
// 赋值后data-src就没用了,移除掉它
imgs[i].removeAttribute('data-src');
}
}
}
}
// 刚进首页不触发滚动事件,因此要先加载一次
lazy();
// 监听滚动事件
window.addEventListener('scroll', lazy);
getBoundingClientRect实现
console.log('getBoundingClientRect实现');
// 懒加载
function lazy() {
// 获取页面高度
let windowHeight =
window.innerHeight || document.documentElement.clientHeight;
// 获取所有img标签
var imgs = document.querySelectorAll('img');
// 延迟加载图片
for (let i = 0; i < imgs.length; i++) {
// 获取每个img标签距离body的高度
let top = imgs[i].getBoundingClientRect().top;
/**
* 如果图片相对屏幕的top值大于屏幕的高度,则代表没出现在屏幕
*/
if (top > 0 && top <= windowHeight) {
const imgSrc = imgs[i].getAttribute('data-src');
// 如果有data-src属性,将它的值赋给src
if (imgSrc) {
imgs[i].src = imgSrc;
// 赋值后data-src就没用了,移除掉它
imgs[i].removeAttribute('data-src');
}
}
}
}
// 刚进首页不触发滚动事件,因此要先加载一次
lazy();
// 监听滚动事件
window.addEventListener('scroll', lazy);
IntersectionObserver实现(推荐)
console.log('IntersectionObserver实现');
// 获取所有img标签
const imgs = document.querySelectorAll('img');
//监听回调
const callback = (entries) => {
entries.forEach((item) => {
// 是否相交
if (item.isIntersecting) {
const ele = item.target;
const imgSrc = ele.getAttribute('data-src');
if (imgSrc) {
ele.src = imgSrc;
// 加载过清空路径,避免重复加载
ele.removeAttribute('data-src');
}
}
});
};
const imgObserver = new IntersectionObserver(callback);
imgs.forEach((item) => {
imgObserver.observe(item);
});
最后更新于:2022-09-13 20:56:53
欢迎评论留言~
0/400
支持markdownComments | 0 条留言
登录
按时间
按热度
目前还没有人留言~