renjie-run / blog

Personal Blog
2 stars 0 forks source link

Web 前端如何获取图片宽高? #21

Open renjie-run opened 4 years ago

renjie-run commented 4 years ago

在后台没有返回图片宽高的情况,前端能够通过哪些方式来获取到一个图片的宽高呢?

获取方式

onload

也就是等待图片加载完毕后再获取宽高,这种方式的缺点就是当要加载的图片比较大时等待的时间会较长。通常该方式会利用缓存配合图片 complete 属性来提升非首次加载的性能。

const imgSrc = '图片地址';
let img = new Image();
img.src = imgSrc;

if (img.complete) {
  console.log(img.width, img.height); // 图片有缓存后执行
} else {
  img.onload = () => {
    console.log(img.width, img.height); // 图片首次加载执行
  }
}

定时器循环检测获取

这种方式对使用场景有一定要求,须谨慎使用。

const imgSrc = '图片地址';
let img = new Image();
img.src = imgSrc;

const check = () => {
  document.body.innerHTML = `<div style="border=1px solid red; width: ${img.width}px; height: ${img.height}px;"></div>`;
}

const timer = setInertval(check, 40);
clearInterval(timer);

应用

图片列表中循环获取每个图片宽高

为每个图片构造一个相应的 Promise 对象,利用 await 获取到每张图片的大小。

构造 Promise 对象。

function addImageProcess(src) {
  return new Promise((resolve, reject) => {
    let img = new Image();
    if (img.complete) {
      resolve({height: img.height || 0, width: img.width || 0});
    } else {
      img.onload = () => resolve({height: img.height || 0, width: img.width || 0});
    }
    img.onerror = ()=> reject(`failed load image: ${src}`);
    img.src = src;
  });
}

获取图片数据。

await addImageProcess(sCover).then((res) => {
  const { width, height } = res || {};
  console.log(width, height);
});

如果你有更好的方式,欢迎留言。