JavaScript实现图片懒加载

什么叫懒加载?

懒加载是相对于预加载的一个概念。预加载是在用户查看之前加载数据,等用户查看的时候,能够很快显示。而懒加载是延时加载,就是在用户需要用到的时候再去加载,可以减少请求次数、降低内存消耗。

比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可视区域装不下,那么懒加载就是优先加载可视区域的内容,其他部分等进入了可视区域在加载。

 

懒加载原理

一张图片就是一个<img>标签,浏览器是否发起请求图片是根据<img>的src属性,所以实现懒加载的关键就是:在图片没有进入可视区域时,先不给<img>的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。

 

相关API

首先介绍几个常用的API:

document.documentElement.clientHeight    //获取屏幕可视区域的高度,不包括水平滚动条、边框和外边距

element.offsetTop    //获取元素相对于文档顶部的高度,注意是HTML文档顶部,也就是整个页面

document.documentElement.scrollTop    //获取浏览器窗口顶部与文档顶部之间的距离,也就是竖直滚动条已经滚动的距离

以下图片可以方便我们理解这三个概念:

懒加载常用API

根据这些我们可以得到一个判断公式:

如果图片进入了可视区内,相当于:offsetTop-scroolTop<clientHeight,则被请求。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>懒加载</title>
		<style>
			.top{
				height: 800px;
				width: 100%;
				background-color: aqua;
			}
			img {
				display: block;
				width: 100%;
				height: 722px;
			}
		</style>
	</head>
	<body>
		<div class="top"></div>
		<img data-src="./image1.jpg" src=""/>
		<img data-src="./image2.jpg" src=""/>
		<img data-src="./image3.jpg" src=""/>
		<img data-src="./image4.jpg" src=""/>
		<img data-src="./image5.jpg" src=""/>
		<script>
			function lazyLoad(imgs){
				var c = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight;
				var s = document.documentElement.scrollTop || document.body.scrollTop;
				for(img of imgs){
					let o = img.offsetTop;
					if(o < c + s){
						console.log('src', o, c, s)
						img.src = img.getAttribute('data-src');
						img.className='img'
					}
					
				}
			}
			var imgs = document.querySelectorAll('img');
			window.onload = window.onscroll = function(){
				lazyLoad(imgs);
			}
		</script>
		
	</body>
</html>

更加简单快捷的API:getBoundingClientRect()

getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, bottom, left, right, width, height等属性。

  • element.getBoundingClientRect().top:元素上边到视窗上边的距离;
  • element.getBoundingClientRect().right:元素右边到视窗左边的距离;
  • element.getBoundingClientRect().bottom:元素下边到视窗上边的距离;
  • element.getBoundingClientRect().left:元素左边到视窗左边的距离;
  • element.getBoundingClientRect().width:元素的宽度;
  • element.getBoundingClientRect().height:元素的高度
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>懒加载</title>
		<style>
			html, body, ul{
				margin: 0;
			}
			li{
				list-style: none;
				height: 200px;
			}
			img{
				height: 200px;
			}
		</style>
	</head>
	<body>
		<ul>
			<li data-src="http://cover.read.duokan.com/mfsv2/download/fdsc3/p01N203pHTU7/Wr5314kcLAtVCi.jpg!t"></li>
			<li data-src="http://77fkxu.com1.z0.glb.clouddn.com/20160308/1457402219_73571.jpg"></li>
			<li data-src="http://cover.read.duokan.com/mfsv2/download/fdsc3/p01a3SXHo2hZ/XYAC5TLk4uYWXn.jpg!t"></li>
			<li data-src="http://pic1.cxtuku.com/00/16/18/b3809a2ba0f3.jpg"></li>
			<li data-src="http://cover.read.duokan.com/mfsv2/download/fdsc3/p015trgKM7vw/H0iyDPPneOVrA4.jpg!t"></li>
			<li data-src="http://77fkxu.com1.z0.glb.clouddn.com/20160308/1457402219_73571.jpg"></li>
			<li data-src="http://imgsrc.baidu.com/baike/pic/item/2f9cbdcc5e0bcf5c00e9283b.jpg"></li>
			<li data-src="http://pic1.cxtuku.com/00/16/18/b3809a2ba0f3.jpg"></li>
			<li data-src="http://cover.read.duokan.com/mfsv2/download/fdsc3/p015trgKM7vw/H0iyDPPneOVrA4.jpg!t"></li>
			<li data-src="http://77fkxu.com1.z0.glb.clouddn.com/20160308/1457402219_73571.jpg"></li>
			<li data-src="http://imgsrc.baidu.com/baike/pic/item/2f9cbdcc5e0bcf5c00e9283b.jpg"></li>
			<li data-src="http://pic1.cxtuku.com/00/16/18/b3809a2ba0f3.jpg"></li>
		</ul>
		<script>
			var imgs = document.querySelectorAll('li');
			window.onload = window.onscroll = function(){
				lazyLoad(imgs);
			}
			
			function lazyLoad(imgs){
				var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
				var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
				for(img of imgs){
					const pos = img.getBoundingClientRect();
					if(pos.y>=0 && pos.y<=clientHeight && img.children.length < 1){
						var image = new Image();
						image.src = img.getAttribute('data-src');
						img.style.display = 'inline'
						img.appendChild(image);
					}
				}
			}
		</script>
	</body>
</html>

【参考文献】

https://zhuanlan.zhihu.com/p/55311726

https://blog.csdn.net/w1418899532/article/details/90515969

https://www.cnblogs.com/demodashi/p/8486513.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值