图片懒加载问题求助:Spinner未正常显示且图片重复加载
解决图片懒加载的两个问题:重复显示&占位Spinner不生效
嘿,我来帮你搞定这两个懒加载的坑!先逐个分析问题原因,再给你具体的解决方案:
问题1:实际图片显示两次
这大概率是因为你给<img>标签同时设置了src和data-src,浏览器会优先加载src指向的图片,之后懒加载脚本又会把data-src的地址赋值给src,导致同一张图被加载两次,自然就显示重复了。
解决方案:
- 把真实图片地址放到
data-src属性里,src要么留空,要么用一个1x1的透明base64像素(不用额外发请求,非常方便):<img data-src="你的真实图片地址.jpg" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="图片描述" />
问题2:加载初期显示破损图标,而非Spinner
浏览器遇到src为空或者指向无效资源的<img>时,默认会显示破损图标。你的Spinner没显示,大概率是占位方式不对——要么没给图片容器设置固定尺寸,要么Spinner的CSS没生效。
解决方案:用CSS给懒加载图片添加Spinner背景,同时固定容器尺寸避免布局跳动,具体实现如下:
1. HTML结构
给图片套一个容器,方便控制尺寸和占位:
<div class="lazy-img-wrapper"> <img class="lazy-img" data-src="你的真实图片地址.jpg" alt="图片描述" /> </div>
2. CSS样式
用CSS实现一个纯代码的Spinner(不用额外图片),作为懒加载图片的背景,同时固定容器尺寸:
.lazy-img-wrapper { position: relative; width: 400px; /* 根据你的需求设置宽高 */ height: 300px; overflow: hidden; } .lazy-img { width: 100%; height: 100%; object-fit: cover; /* 保持图片比例 */ /* 纯CSS实现的Spinner背景 */ background: #f0f0f0 url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M25,5A20.14,20.14,0,0,1,45,22.88a2.51,2.51,0,0,0,2.49,2.26h0A2.52,2.52,0,0,0,50,22.33a25.14,25.14,0,0,0-50,0,2.52,2.52,0,0,0,2.5,2.81h0A2.51,2.51,0,0,0,5,22.88,20.14,20.14,0,0,1,25,5Z"><animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"/></path></svg>') center no-repeat; background-size: 40px 40px; } /* 图片加载完成后移除Spinner背景 */ .lazy-img.loaded { background: none; }
3. 懒加载JS(用Intersection Observer,高效且现代)
用浏览器原生的Intersection Observer API监听图片是否进入视口,加载完成后添加loaded类移除Spinner:
document.addEventListener('DOMContentLoaded', () => { const lazyImgs = document.querySelectorAll('.lazy-img'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; // 把data-src赋值给src开始加载 img.src = img.dataset.src; // 加载完成后添加loaded类 img.onload = () => { img.classList.add('loaded'); }; // 停止监听已加载的图片 observer.unobserve(img); } }); }); // 给所有懒加载图片添加监听 lazyImgs.forEach(img => observer.observe(img)); });
额外注意事项
- 如果你需要兼容IE等旧浏览器,可以给Intersection Observer加个polyfill(但现在大部分主流浏览器都支持了)。
- 一定要给
<img>设置alt属性,提升网站的可访问性。 - 不要给
src设置真实图片地址,否则还是会重复加载哦!
内容的提问来源于stack exchange,提问作者juhi
相关产品推荐
相关产品推荐

