Image()函数将会创建一个新的HTMLImageElement实例。它的功能等价于document.createElement('img')
正常情况下,我们使用下面方法加载图片,是能能够获取到onload事件的:

const img = new Image();
img.src = 'picture.jpg';
img.onload = () => {
  console.log('success');
}

但是如果你需要加载的图片是base64图片时,可能是因为没有请求发出,onload事件是无法执行的。
几经尝试,最终考虑将base64图片转位ObjectUrl再加载,好处是无需后端,纯前端即可兼容。移动端兼容性也非常不错。
具体实现如下:

// base64转Blob
const base64ToBlob = (base64Data) => {
  const arr = base64Data.split(','),
    type = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    len = bstr.length,
    u8Arr = new Uint8Array(l);

  while (len--) u8Arr[l] = bstr.charCodeAt(len);

  return new Blob([u8Arr], { type });
}

const base64 = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
const imgBlob = base64ToBlob(base64)

const img = new Image();
img.src = window.URL.createObjectURL(imgBlob); // blob:http://xxx
img.onload = function () {
  console.log('success')
}

URL.createObjectURL可能有一些兼容性问题,如果你在使用过程遇到,可以hack兼容一下

function getObjectURL(blob) {
  var url = null;
  if (window.createObjectURL != undefined) {
    url = window.createObjectURL(blob);
  } else if (window.URL != undefined) {
    url = window.URL.createObjectURL(blob);
  } else if (window.webkitURL != undefined) {
    url = window.webkitURL.createObjectURL(blob);
  }
  return url;
}
本文参考资料:
Image() - Web API 接口参考 | MDN (mozilla.org)
使用img.onload事件加载base64图片的兼容问题 - 简书 (jianshu.com)
vue 上传图片,转base64取不到.onload的值 - 小蘑菇123 - 博客园 (cnblogs.com)
Image()函数加载base64图片无onload事件的前端兼容方案

https://blog.sdgou.cc/archives/146.html

作者

白鸽

发布时间

2022-04-12

许可协议

CC BY-SA 4.0