Skip to content
Menu
Yuuk的博客
  • 首页
  • 前端技术
    • JavaScript
    • HTML & CSS
  • SEO
  • 设计
    • 素材分享
    • 设计教程
  • 随笔
Yuuk的博客

使用IntersectionObserver实现简易的图片懒加载功能

Posted on 2018年4月26日 by yuuk

IntersectionObserver是什么?

IntersectionObserver是一个新的web API,可以自动检测某个元素是否出现在页面可视区,所以有一个通俗的名字叫 “交叉观察器”,Chrome 51+ 已经支持该特性。更详细的介绍可以看看阮一峰大神的文章:《IntersectionObserver API 使用教程》

为什么要用IntersectionObserver特性?

在此之前,我们监听页面元素是否出现在可视区,或者实现图片懒加载都是通过监听 scoll 事件,而scoll事件密集发生,容易造成性能问题。

话不多说,我们开始撸码!

HTML部分

<div class="img-list">
	<ul>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0423/43a7fbe301d6d3a4c1daadd46bda8996.jpg"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0423/d4c853a6b08d285c809c0f22af04f4d5.jpg"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file03.16sucai.com/2017/1100/16sucai_P591F3A175.JPG"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0423/18a5cf4ab618e6736806db42a7a6197b.jpg"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0423/7dcfc1aede6cd99b583f4149e3ad73ac.jpg"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0315/fa9f74d6296cd7a1ad9b79e480556c3f.jpg"></li>
		<li><img src="https://placehold.it/300&text=Loading..." data-src="https://file06.16sucai.com/2018/0315/8fc2da2c3f645e4afe992ac5c401f4f1.jpg"></li>
        </ul>
</div>

CSS部分

<style>
*{padding: 0;margin: 0;list-style: none;}
body {height: auto;width: 300px;margin: auto;}
.img-list li {width: 300px;height: auto;}
.img-list li img {width: 100%;height: auto;}
</style>

JS部分

	<script>
		window.onload = () => {
			var eles = document.querySelectorAll('.img-list li img'); // 获取所有列表元素
			
			// 监听回调
			var callback = (entries) => {
				entries.forEach(item => {
					// 出现到可视区
					if (item.intersectionRatio > 0) {
						var ele = item.target;
						var imgSrc = ele.getAttribute('data-src');
						if (imgSrc) {
							// 预加载
							var img = new Image();
							img.addEventListener('load', function() {
							    ele.src = imgSrc;
							}, false);
							ele.src = imgSrc;
							// 加载过清空路径,避免重复加载
							ele.removeAttribute('data-src');
						}
					}
				})
			}
			var observer = new IntersectionObserver(callback);

			// 列表元素加入监听
			eles.forEach(item => {
				observer.observe(item);
			})
		}
	</script>

实现起来没有什么难度,不过遇到一个问题。当不使用window.onload调用时,由于获取不到元素真实占位,会导致 callback 初次调用时会执行两次(一次是目标元素刚刚进入视口-开始可见,另一次是完全离开视口-开始不可见),这个需要注意。

完整Demo:IntersectionObserver实现懒加载

打赏赞(12)分享

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

搜索

近期文章

  • 宝塔面板中使用docker部署nodejs应用
  • 如何将docker镜像上传到阿里云
  • React Native 报错 No bundle URL present 解决方法
  • axios 给每一个请求添加耗时统计
  • css filter属性导致fixed失效

标签

addEventListener ajax ajax跨域 chatAt css居中 DNS缓存 docker gulp ie7 json jsonp margin memcache mysql nodejs ps技巧 typescript void vpn vuejs wampserver webpack win10 XMLHttpRequest z-index 事件冒泡 事件绑定 内容发布时间 图片加载 大写 字符串 封装ajax 广告屏蔽 批量修改图层名称 水平垂直居中 注册码 特殊符号 百度 空元素 站长平台 网页快照 负边界 递减 随机数 首字母

友情链接

  • 蔡甸新闻网
©2025 Yuuk的博客 | 鄂ICP备13014750号-9