基本步骤
- 引入图片占位:在需要懒加载图片的位置,先使用一个占位元素(如一个空的
<div>
或低质量小图)占据空间,以保证页面布局在图片加载前不会跳动。
- 设置数据属性:给图片元素添加自定义数据属性(如
data - src
),用于存储真实的图片源地址,而 src
属性初始设置为空或一个默认值(如加载占位图)。
- 监听事件:监听页面的滚动事件或使用
IntersectionObserver
来检测图片是否进入视口。
关键技术点
- 判断图片是否进入视口
- 传统滚动事件方法:通过
window.onscroll
监听滚动事件,获取窗口高度(window.innerHeight
)、文档高度(document.documentElement.scrollHeight
)以及滚动条位置(window.pageYOffset
或 document.documentElement.scrollTop
)。对于每个需要懒加载的图片,计算其相对于视口的位置,如果图片距离视口顶部的距离小于窗口高度加上滚动条位置,即认为图片进入视口。例如:
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
- **IntersectionObserver**:这是浏览器提供的一个异步 API,用于异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉变化情况。创建 `IntersectionObserver` 实例时,传入一个回调函数,当目标元素进入或离开视口时,该回调函数会被触发。示例代码如下:
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
const lazyImages = document.querySelectorAll('img[data - src]');
lazyImages.forEach(img => {
observer.observe(img);
});
- 加载图片:当判断图片进入视口后,将
data - src
的值赋给 src
属性,触发图片加载。
- 错误处理:为图片元素添加
error
事件监听器,在图片加载失败时,可以进行相应处理,如显示替代文本或重新尝试加载。例如:
img.addEventListener('error', function () {
this.src = 'fallback - image - url.jpg';
});