1. 实现拆分
滑动的页面内容抵达当前视图窗口, 图片加载
- 判断图片出现在当前视图窗口
- 控制图片加载
2. 判断图片出现在当前视图窗口
2.1 dom位置计算1
- 通过window.onload事件初始化计算
- 通过window.scroll事件监听触发, 实现动态计算
- 视图高度和滚动顶部距离与图片的顶部距离作对比, 得出是否出现在当前视图中
js
视图scrollTop + 视图clientHeight > 图片offsetTop
2.2 getBoundingClientRect API获取
- 通过window.scroll事件监听触发, 实现动态计算, 并且 节流 处理, 减少判断次数
- ele.getBoundingClientRect() 可获取元素大小及相对视图的位置
- getBoundingClientRect().top: 相对视图窗口的顶部距离
- clientHeight: 当前视口的高度
当网页往下滚动时, 图片距离视窗口的顶部距离就越来越小, 即getBoundingClientRect的top变小, 当顶部距离和视图窗口的高度一致时, top === clientHeight. 图片即将进入视图窗口, 紧贴在视图窗口的下方. 所以得出视图内公式
js
img.getBoundingClientRect().top < document.documentElement.clientHeight
无需关注图片滚动到视图窗口的上方, 目的是做懒加载, 已经加载过了.
IE浏览器兼容
2.3 IntersectionObserver API获取
前面方法依赖两步
- window.scroll监听, 节流
- 位置计算
浏览器出了一个IntersectionObserver事件, 用于监听元素是否到达可视窗口
js
const observer = new IntersectionObserver((changes) => {
// changes: 监听的所有目标元素集合
changes.forEach((change) => {
// intersectionRatio
if (change.isIntersecting) { // 是否在可视窗口内
// 控制图片加载
const img = change.target; // 目标元素
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
observer.observe(img); // 监听元素
IE浏览器不兼容
3.3 LazyLoading 属性
html
<img src="demo.jpg" loading="lazy" />
一行html即可, 但兼容性差
3. 控制图片加载
3.1 DataSet Api
在html中设置图片的data-src属性
html
<img data-src="xx.png">
在需要加载时, 将其设置 img.src = img.dataset.src