例如我们想图片一次性加载出来再显示,之前则显示默认的占位符
export default function Image() {
const [loaded, setLoaded] = useState<boolean>(false)
const handleLoaded = () => {
setLoaded(true)
}
return (
<div>
{
// 未加载成功显示占位符组件
!loaded && <PlaceholderImage />
}
<img
src="xxxxx"
style={{ opacity: loaded ? 1 : 0 }}
onLoad={handleLoaded}
/>
</div>
)
}
当在 Chrome 上使用 ctrl + F5 刷新的时候,图片可以正常显示,onLoad 事件正常被触发。但是再次执行普通刷新的时候,由于图片会使用缓存,此时发现 onLoad 事件并不会被触发,img 的 opacity 属性一直为 0,图像未显示。
经过搜索,发现也有人遇到类似问题:stackoverflow
我们可以使用 HTMLImageElement.complete 属性来判断是否加载完成。改进上述代码:
export default function Image() {
const [loaded, setLoaded] = useState<boolean>(false)
const imgRef = useRef<HTMLImageElement>()
const handleLoaded = () => {
setLoaded(true)
}
// 在渲染后通过 complete 属性判断是否加载完成
useEffect(() => {
if (imgRef.current.complete) {
setLoaded(true)
}
}, [])
return (
<div>
{!loaded && <PlaceholderImage />}
<img
src="xxxxx"
ref={imgRef}
style={{ opacity: loaded ? 1 : 0 }}
onLoad={handleLoaded}
/>
</div>
)
}
注意: 图片src或者srcset属性为空时,complete属性也会变为true