为什么我的图片懒加载在滚动到底部时会重复加载?
我在做一个图片列表页用懒加载,用Intersection Observer监听,但滚动到页面最底部时,图片会重复触发加载两次。之前试过把阈值改成0.1和调整根边距都不行,控制台还报错说”Cannot read properties of undefined (reading ‘src’)”。
代码是这样的:observer.observe(document.querySelectorAll('.lazy-img')),然后回调里用entries.forEach(entry => { if (entry.isIntersecting) { ... }}。但发现当最后一个元素出现时,回调执行了两次,导致重复请求和错误。
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
});
}, { rootMargin: '0px', threshold: 1.0 });
document.querySelectorAll('.lazy-img').forEach(img => observer.observe(img));
一是 threshold 设为 1.0 太大了,需要元素完全进入视口才触发,这样在边界处很容易触发多次。
二是
entry.target可能在某些情况下取不到,应该加个保险。改一下:
改动点:
rootMargin 改成 '100px',让图片在距离视口100px时就开始加载,这样用户还没看到就加载完了,体验更好。
threshold 改成 0,只要元素一出现就触发,别等完全进入。
加了
entry.target和src的判断,防止报错。加载完记得调用 unobserve 取消监听,这样就不会重复触发了。
另外建议给 img 标签加个初始的 src 用占位图或者空字符串,避免加载时出现破图。