如何判断一组图片在页面上是否加载完成呢

4 分钟
37 阅读
如何判断一组图片在页面上是否加载完成呢

判断图片加载完成的几种方法

判断图片是否加载完成是前端开发中的常见需求,以下是几种可靠的方法:

1. 使用 onloadonerror 事件

javascript 复制代码
const images = document.querySelectorAll('img');

images.forEach(img => {
  // 图片加载成功
  img.onload = function() {
    console.log(`${img.src} 加载完成`);
  };
  
  // 图片加载失败
  img.onerror = function() {
    console.error(`${img.src} 加载失败`);
  };
  
  // 如果图片已经缓存且加载完成
  if (img.complete) {
    if (img.naturalWidth === 0) {
      console.error(`${img.src} 加载失败(缓存)`);
    } else {
      console.log(`${img.src} 已缓存`);
    }
  }
});

2. 使用 Promise 判断所有图片

javascript 复制代码
function imageLoaded(img) {
  return new Promise((resolve, reject) => {
    if (img.complete) {
      return resolve(img);
    }
    img.onload = () => resolve(img);
    img.onerror = () => reject(img);
  });
}

// 判断所有图片
Promise.all(
  Array.from(document.images).map(img => 
    imageLoaded(img).catch(img => img)
  )
).then(() => {
  console.log('所有图片加载完成(包括失败的)');
});

3. 监听动态添加的图片

javascript 复制代码
const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    mutation.addedNodes.forEach(node => {
      if (node.nodeName === 'IMG') {
        imageLoaded(node)
          .then(() => console.log('动态图片加载完成:', node.src))
          .catch(() => console.error('动态图片加载失败:', node.src));
      }
    });
  });
});

observer.observe(document.body, {
  childList: true,
  subtree: true
});

4. 使用 loading 属性 + IntersectionObserver(懒加载场景)

javascript 复制代码
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
const io = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.onload = () => {
        console.log('懒加载图片完成:', img.src);
        observer.unobserve(img);
      };
      img.onerror = () => {
        console.error('懒加载图片失败:', img.src);
        observer.unobserve(img);
      };
    }
  });
});

lazyImages.forEach(img => io.observe(img));

5. 检查图片状态综合方法

javascript 复制代码
function checkImageStatus(imgs) {
  return Array.from(imgs).map(img => {
    return {
      element: img,
      loaded: img.complete && img.naturalWidth !== 0,
      failed: img.complete && img.naturalWidth === 0,
      src: img.src
    };
  });
}

// 使用示例
const status = checkImageStatus(document.images);
console.table(status);

注意事项

  1. 缓存图片:已缓存的图片会立即触发 complete 属性为 true
  2. 跨域问题:如果图片来自不同域且没有 CORS 头,可能无法准确获取 naturalWidth
  3. SVG 图片:某些浏览器对 SVG 的 complete 属性支持不一致
  4. CSS 背景图:上述方法不适用,需使用 window.getComputedStyle() 配合其他技巧

性能优化建议

对于大量图片,建议使用批量检测+分片处理:

javascript 复制代码
async function checkAllImagesLoaded() {
  const images = Array.from(document.images);
  const BATCH_SIZE = 10;
  
  for (let i = 0; i < images.length; i += BATCH_SIZE) {
    const batch = images.slice(i, i + BATCH_SIZE);
    await Promise.all(batch.map(img => imageLoaded(img)));
    console.log(`已完成 ${Math.min(i + BATCH_SIZE, images.length)}/${images.length}`);
  }
  
  console.log('所有图片处理完成');
}

选择适合你场景的方法即可高效判断图片加载状态。

评论

评论

发表评论