html5怎么检测图片加载完成_html5加载状态判断【代码】

11次阅读

监听图片加载需先绑定load/Error事件再设src,或检查img.complete;推荐用promise封装,并在load后调用decode()确保解码完成,再结合IntersectionObserver实现可靠懒加载

html5怎么检测图片加载完成_html5加载状态判断【代码】

图片加载成功或失败如何监听

html5 中没有专门的「加载状态 API」,但 html5怎么检测图片加载完成_html5加载状态判断【代码】 元素原生支持 loaderror 事件,这是判断加载完成最直接、最可靠的方式。注意:这两个事件只触发一次,且仅在浏览器开始解析完图片数据(含解码)后才触发。

常见错误是监听 onload 但没处理缓存场景——已缓存的图片可能在 addEventListener 绑定前就完成了加载,导致事件丢失。必须在设置 src 之前绑定事件,或检查 complete 属性:

  • img.complete === true 表示图片已加载完毕(含缓存、空 src、data URL 等情况)
  • completetrue,可立即执行成功逻辑,无需等事件
  • completefalse,再监听 load/error

Promise 封装图片加载更可控

手动管理事件容易出错,尤其在批量加载或配合 async/await 时。封装成 Promise 是现代做法,能统一处理成功与失败路径:

function loadImage(src) {   return new Promise((resolve, reject) => {     const img = new Image();     img.onload = () => resolve(img);     img.onerror = () => reject(new Error(`Failed to load image: ${src}`));     img.src = src;   }); }  // 使用 loadImage('/logo.png')   .then(img => console.log('loaded', img.naturalWidth))   .catch(err => console.error(err));

注意点:

立即学习前端免费学习笔记(深入)”;

  • 不要用 document.createElement('img')append 到 body —— 不必要,还可能触发重排
  • new Image() 创建的是无 dom 的图像对象,轻量且安全
  • 如果需兼容 IE9+,该写法完全可用;IE8 及以下不支持 Promise,需 polyfill 或回调替代

decode() 方法才是真正的「解码完成」信号

很多开发者以为 load 事件代表图片可渲染,其实不然。load 只表示资源下载并解析完成,但大图(尤其 WebP/HEIC)可能尚未解码,首次绘制仍会卡顿。html5 新增的 decode() 方法可显式等待解码结束:

img.addEventListener('load', async () => {   try {     await img.decode(); // 返回 Promise,解码完成才 resolve     console.log('Ready to render without jank');   } catch (err) {     console.error('Decode failed', err);   } });

关键细节:

  • decode()safari 14+、chrome 54+、firefox 69+ 支持,edge 基于 Chromium 后也支持
  • 调用前必须确保 img.complete === true,否则抛错
  • 对小图影响不大,但对 >2MB 的高清图或懒加载场景,能避免首帧闪烁或 layout shift

懒加载图片怎么判断「真正可见并加载完」

单纯用 IntersectionObserver 监听进入视口,不等于图片已加载完成。典型坑是:元素刚进入视口就设置 src,但用户快速滚动,load 还没触发就移出视口,导致状态不可知。

稳妥做法是组合使用:

  • IntersectionObserver 触发加载(设 src
  • Promise.all(图片加载 Promise 数组) 聚合所有待加载项
  • 加载完成后才更新 ui 或取消 loading 状态
  • 对已 complete 的图片跳过重复加载(比如用户来回滚动)

最容易被忽略的一点:img.naturalWidth === 0 在加载失败或跨域未配 CORS 时也可能为真,不能单靠它判断是否成功 —— 必须以 load / error 事件或 decode() 结果为准。

text=ZqhQzanResources