如何实现图片懒加载

本文深入解析懒加载技术,介绍其作为网页性能优化手段的工作原理,包括如何延迟加载图片,以及三种判断元素是否在可视区域的方法:通过计算元素位置、使用getBoundingClientRect()和IntersectionObserver API。文章还提供了具体的实现代码。
原文来自微信公众号:web前端学习圈

什么是懒加载?
懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示的时候再发送图片请求,避免打开网页时加载过多资源。

懒加载原理
img标签有一个属性是 src,用来表示图像的URL,当这个属性的值不为空时,浏览器就会根据这个值发送请求。如果没有 src属性,就不会发送请求。
故,我们先不给img设置 src,把图片真正的URL放在另一个属性 data-src中,在需要的时候也就是图片进入可视区域的之前,将URL取出放到 src中。

<div class="img-area">
	<img class="my-photo" alt="loading"  data-src="./img/img1.png">
</div>

alt 属性是一个必需的属性,它规定在图像无法显示时的替代文本。 data-src 全局属性:构成一类名称为自定义数据属性的属性,可以通过
HTMLElement.dataset来访问。

如何判断元素是否在可视区域

方法一

  1. 通过 document.documentElement.clientHeight获取屏幕可视窗口高度
  2. 通过 document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离
  3. 通过 element.offsetTop获取元素相对于文档顶部的距离

然后判断②-③<①是否成立,如果成立,元素就在可视区域内。

方法二

通过 getBoundingClientRect()方法来获取元素的大小以及位置,这个方法返回一个名为 ClientRect的 DOMRect对象,包含了 top、 right、 botton、 left、 width、 height这些值。
假设 constbound=el.getBoundingClientRect();来表示图片到可视区域顶部距离; 并设 constclientHeight=window.innerHeight;来表示可视区域的高度。

随着滚动条的向下滚动, bound.top会越来越小,也就是图片到可视区域顶部的距离越来越小,当 bound.top===clientHeight时,图片的上沿应该是位于可视区域下沿的位置的临界点,再滚动一点点,图片就会进入可视区域。

也就是说,在 bound.top<=clientHeight时,图片是在可视区域内的。
页面打开时需要对所有图片进行检查,是否在可视区域内,如果是就加载。

function checkImgs() {
		const imgs = document.querySelectorAll('.my-photo');
		Array.from(imgs).forEach(el => {
			if (isInSight(el)) {
				loadImg(el);
			}
		})
	}
	function loadImg(el) {
		if (!el.src) {
			const source = el.dataset.src;
			el.src = source;
		}
	}

方法三 IntersectionObserver

IntersectionObserver可以自动观察元素是否在视口内。
在这里插入图片描述

function checkImgs() {
		const imgs = Array.from(document.querySelectorAll(".my-photo"));
		imgs.forEach(item => io.observe(item));
	}
	function loadImg(el){
		if (!el.src) {
			const source = el.dataset.src;
			el.src = source;
		}
	}
	const io = new IntersectionObserver(ioes => {ioes.forEach(ioe => {
			const el = ioe.target;
			const intersectionRatio = ioe.intersectionRatio;
			if (intersectionRatio > 0 && intersectionRatio <= 1) {
				loadImg(el);
			}
			el.onload = el.onerror = () => io.unobserve(el);
		});
	});

附上阮一峰链接:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值