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)

标签: js, 前端, javascript, base64, Image

已有 37 条评论

  1. 大佬更新了啊

    1. 居家办公又有时间折腾了

  2. 哟嚯,更新了 居然也更换了板子 清新又简洁 真他娘好看

    1. 确实难得更新一次😄

  3. 大佬厉害了,更新了

  4. 48534 48534

    上海那边怎么样啦

    1. 解封遥遥无期,今天抗原检测我们这栋楼有阳性,等待进一步核酸确认。

  5. 当初想着把博客图片全部转base64,然后图片太大转换中直接把电脑搞死机了哈哈哈。

    1. 想不开呀,base64太占空间了,而且会影响搜索性能。还影响首屏加载性能,为了减少一点点请求得不偿失

      1. 确实因小失大了。

        奇怪了竟然没收到邮件通知!!上次都有。

        1. 不会吧,不清楚是不是进了黑名单,之前用的是阿里云的邮件推送服务,刚刚换成了腾讯企业邮箱发信,你现在能收到吗?

          1. 现在收到了,上条评论的没收到。

  6. 难得更新哦,注意安全。主题很好看

  7. 留言好高级,自动调取

    1. 你博客怎么直接关闭评论了

      1. 嗨..也没几个人评论..

  8. 博主啥时候开放当前主题下载呀????嘻嘻嘻~超喜欢

  9. 文章更新,主题也更新了。都不错啊。

  10. 每年一更,哈哈……

    1. 今年会勤快那么一丢丢

  11. 大佬不仅文章更新了,主题也更新了

  12. 看了很久还是看不懂.

    1. 你写的Java和sql我也晦涩难懂😂

      1. 牛啊,邮件回复的头像居然也是base64的.

        1. 不然邮箱会拦截第三方图片,还要信任发件人,体验不好。

          1. 不亏是跟我一样的细节控.

  13. 问题解决了

  14. jiandan jiandan

    想问一下博主,用了哪些方法优化WordPress,速度很快呢

  15. fuza fuza

    博主的服务器配置是?

    1. 1C1G的HK轻量 腾讯云,暂时只放了一个博客,配置绰绰有余

  16. 又换新theme了……啧啧~

    1. 居家办公就多了很多自己的时间😂

  17. 你活了

    1. 倒也没有完全活,2333

  18. 一段时间没来了,居然壳都换了。ObjectURL常用于前端图片上传回显,图片本身会置于内存中。你打算在上海定居了么?北京疫情现在没那么严重。

    1. 文章解决的不是常规的回显问题,因为base64图片加载成功无法响应onload事件。定居暂时还是比较朦胧的想法,没钱😂

  19. 学习👏👏

添加新评论