图片加载错误的捕获及处理

news2024/9/24 15:27:15

引言

前端开发中,图片是我们在网页中加载最多的静态资源类型之一,但是图片加载过程中也有可能出现加载失败的情况,这是十分影响用户体验的。那么如何正确的判断图片是否成功加载,以及图片加载失败的时候,如何处理,就是本篇文章所要讲解的主要内容。

设置alt属性

我们看看w3c对这个属性的解释。

5a01f242d1217f0fb1efcdde4630d910.png

它的用法也非常简单,直接给img标签加上这个属性就行。

<img src="https://p4.ssl.qhimg.com/t019f326a5524ce5fcc.png" />
            <img src="https://p5.ssl.qhimg.com/t0139228d9f6f26225c.png" />
            <img
              src="https://p5.ssl.qhimg.com/t01950dfde27027b6191.jpg"
              alt="图片加载失败啦"
            />
8ea64107b5df5efe1c5730503d287b31.png

但是这种效果其实是不太理想的,这个一张默认破裂的图片,然后alt的内容作为文字提示,用户可以通过文案知道,图片加载失败了。上述这种方式虽然达到了目标,但是确实算得上比较的粗糙。后续我们还有更好的手段来进行优化。

设置兜底图

这是图片错误处理中最常用的手段,后续代码都是基于react来进行演示。

单个元素处理

这种处理方法类似于图片懒加载,图片没有完全加载的时候,我们给予img标签一张默认的图片,当图片加载失败时,就展示我们兜底图。

第一步就是如何判断我们的图片是否加载错误,img标签有一个onerror事件,下面是mdn对该事件的描述。

d3af09afb751dde113d9132d5b2c8ac0.png

当我们的图像在加载过程中发生了错误,几乎都会触发该事件,我们就可以利用这个事件,进行针对性的处理了。像下面这样

<img src="https://p4.ssl.qhimg.com/t019f326a5524ce5fcc.png" />
            <img src="https://p5.ssl.qhimg.com/t0139228d9f6f26225c.png" />
            <img
              src="https://p5.ssl.qhimg.com/t01950dfde27027b6191.jpg"
              onError={handleImgError}
            />
const handleImgError = (e: any) => {
    console.log("e", e.target);
    e.target.src = "https://p3.ssl.qhimg.com/t011d7a9a61e6d6be72.png";
  };

上述代码实现效果如下,第三张图加载失败,但是我们的默认兜底图生效,整体看起来就比前面和谐不少。

e8e4a310c704a952d8d7f82860f3f47d.png

统一捕获错误

前面我们通过给img标签绑定onerror事件,来达到了对目标图片实现加载失败的兜底,但是实际页面,可能会有很多张图片,如果我们对每张图片都单独绑定处理的函数,不仅麻烦,而且可能会有遗漏,后期也不好维护。

所以我们可以改进一下处理方法,通过监听全局的error事件,然后判断触发error事件的元素是不是Img标签,是Img标签产生,我们就对图片src进行对应的更改。

window.addEventListener(
      "error",
      function (event) {
        const target = event.target;
        if (target instanceof HTMLImageElement) {
          target.src = "https://p3.ssl.qhimg.com/t011d7a9a61e6d6be72.png";
          console.log("图片加载异常", target);
        }
      },
      true
    );
<img src="https://p4.ssl.qhimg.com/t019f326a5524ce5fcc1.png" />
            <img src="https://p5.ssl.qhimg.com/t0139228d9f6f26225c.png" />
            <img src="https://p5.ssl.qhimg.com/t01950dfde27027b6191.jpg" />
d6ca0e22e2812b07b08d49f84fc10786.png

我们可以看到,我们没有对Img标签添加额外的属性,减少了额外的开销。对于多张图片的错误也能进行较好的处理。

base64编码

图片加载的失败的原因有很多,在上边的例子中,我都是使图片原始src的地址无效,响应404,来模拟图片加载错误,但是如果是因为网络质量问题等原因造成的加载失败,那么加载兜底图的资源,也有可能会失效,还会无限触发error事件。所以我们还需要进一步的优化,让图片不需要从远程服务器获取静态资源。我们此时就可以想到,img标签可以直接加载base64格式的图片,而我们可以将base64作为字符串,硬编码在我们的代码里面。加载代码的时候,图片就已经相当于被加载完成。

const errorImg ='base64字符串'; //因为base64字符串较长,所以这里就不贴上具体base64字符串
    window.addEventListener(
      "error",
      function (event) {
        const target = event.target;
        if (target instanceof HTMLImageElement) {
          target.src = errorImg;
          console.log("图片加载异常", target);
        }
      },
      true
    );

通过上面的代码我们就避免了兜底图加载失败的时候,会无限触发error事件的尴尬,但是base64本身的特性就决定了图片就会比原来大上1/3左右,所以我们选择兜底图时,应该尽量控制图片的体积,避免打包后的js文件,因此变得过大。

css处理

上述的实现都是完全依靠js代码进行实现,我们利用css也可以实现上述类似的效果,通过css来完成的话,可以使得我们对错误样式有更大的可定制性。这就要用到css中的伪元素来实现。对错误的捕获我们依然沿用前面的方法,但是后续的处理,我们可以不用添加兜底图片。

window.addEventListener(
      "error",
      function (event) {
        const target = event.target;
        if (target instanceof HTMLImageElement) {
          target.classList.add("error"); //添加对应的类名
        }
      },
      true
    );
<img src="https://p4.ssl.qhimg.com/t019f326a5524ce5fcc.png" />
            <img src="https://p5.ssl.qhimg.com/t0139228d9f6f26225c.png" />
            <img src="https://p5.ssl.qhimg.com/t01950dfde27027b6191.jpg" />
.error {
  position: relative;
  width: 100px;
  height: 100px;
}
img.error::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #f5f5f5;
  color: transparent;
}
img.error::after {
  content: "图片加载出错啦!";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  line-height: 100px;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

当图片加载错误的时候,我们给图片添加了一个自定义类名,然后通过伪元素实现自定义错误样式,before设置背景样式,after设置提示文案。效果如下图所示。

3e3b4a5d6fcac7bc64ff0b72b2b51936.png

这里的样式我们只做了最基础的设置,具体可以根据场景进行美化。我们没有引入任何的图片资源,也实现了和前面类似的效果,当然如果想实现图片的加入,也十分简单,我们只需要在before中插入对应的base64格式图片即可。

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

a1c2898e36d09f3caf043ae0e59f38b7.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/672600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解 Dockerfile 和搭建 Docker 私有仓库:让容器化部署变得更简单

目录 1、Dockerfile 1.1什么是Dockerfile 1.2常用命令 1.3使用脚本创建镜像 2、Docker私有仓库 2.1私有仓库介绍&#xff1a; 2.2私有仓库搭建与配置 2.3上传镜像到私有仓库&#xff1a; 1、Dockerfile 1.1什么是Dockerfile Dockerfile是由一些列命令和参数构成的脚本…

【服务器数据恢复】IBM存储分配的卷无法访问的数据恢复案例

服务器故障&#xff1a; 一台IBM DS存储出现故障&#xff0c;存储分配给aix小机的卷无法访问。从底层查看分配给aix小机的3个卷的lvm信息丢失。 服务器数据恢复过程&#xff1a; 1、将存储中所有磁盘编号后取出&#xff0c;以只读方式做全盘镜像&#xff0c;后续的数据分析和数…

【C++篇】字符串:标准库string类

友情链接&#xff1a;C/C系列系统学习目录 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的…

Eyeshot 2023 Added NuGet packages.

Added Microsoft Visual Studio 2022 Extensions menu item.Microsoft .NET 6 Windows Toolbox items.Added NuGet packages.Planar curve projection on Sketch plane.Improved fillet surfaces quality and speed.Added ICurve.ConverToLinearPath() family of methods.   …

RabbitMQ学习笔记4(小滴课堂)RabbitMQ工作队列模型实战

Java项目整合RabbitMQ 创建一个maven项目。 然后我们在maven里加上jdk和rabbitmq的依赖设置&#xff1a; 我们写一段生产者的代码&#xff1a; 然后我们去运行它&#xff1a; 可以看到这里有一个队列。 现在我们是可以查看到队列的。 我们去写消费者代码&#xff1a; 这里的之…

LeetCode 2090. K Radius Subarray Averages【前缀和,滑动窗口,数组】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Redis是什么,如何学习,如何整合SpringBoot?

目录 一、Redis是什么&#xff1f; 二、如何学习Redis 三、如何整合SpringBoot 一、Redis是什么&#xff1f; Redis 是一个高性能的开源 NoSQL 数据库&#xff0c;支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合和有序集合等。它采用内存存储&#xff0c;可以快…

Python3 函数与数据结构 | 菜鸟教程(十一)

目录 一、Python3 函数 &#xff08;一&#xff09;定义一个函数 1、你可以定义一个由自己想要功能的函数&#xff0c;以下是简单的规则&#xff1a; 2、语法 3、实例 ①让我们使用函数来输出"Hello World&#xff01;"&#xff1a; ②更复杂点的应用&#xff…

axios 发送请求请求头信息不包含Cookie信息

问题 axios 发送请求请求头信息不包含Cookie信息 详细问题 使用VueSpringBoot进行项目开发&#xff0c;axios进行网络请求&#xff0c;发送请求&#xff0c;请求头信息不包含Cookie信息 具体如下 实际效果 预期效果 解决方案 作用域 Vue项目全局配置 打开Vue项目的入口…

SpringSecurity是什么,如何学习SpringSecurity?

目录 一、SpringSecurity是什么 二、如何学习SpringSecurity 三、SpringSecurity整合springboot 一、SpringSecurity是什么 Spring Security是一个功能强大的安全框架&#xff0c;它为企业级应用程序提供了完整的身份验证和授权管理。它是一个开源项目&#xff0c;由Pivota…

Linux:第五章课后习题及答案

第五章 Linux常用命令 Q1&#xff1a;常用的文本内容显示命令有哪些&#xff1f;区别是什么&#xff1f; 文本内容显示的命令有cat&#xff0c;more&#xff0c;less&#xff0c; head&#xff0c;tailcat&#xff1a;显示文本文件&#xff0c; 也可以把几个文件 内容附加到另…

第一章 AlexNet网络详解

系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网络详解 第七章 MobileNetv2网络详解 第八章 MobileNetv3网络详解 第九章 ShuffleNetv1网络详解 第十章…

python绘画多边形(turtle)

目录 前言 正三角形 正四边形 正多边形 总结&#xff1a; 前言 事情的起因是&#xff0c;我今天心血来潮想让openai生成路飞的图像看效果怎么样&#xff0c;他是这样回我的。 我这一想&#xff0c;这不稳了吗&#xff0c;这么轻松。结果…… import turtle# 定义画笔颜色…

【Visual Studio】报错 C1083,使用 C++ 语言,配合 Qt 开发串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 问题解决方案Ref. 问题 使用 C 语言&#xff0c;配合 Qt 开发串口通信界面时&#xff0c;报错代码 C1083。 复制一下错误信息&#xff0c;方便别人…

【C语言进阶】编译链接

文章目录 &#x1f4d6;程序的两种环境 &#x1f516;翻译环境&#x1f516;执行环境 &#x1f4d6;详解翻译环境&#x1f516;从人的角度去看编译链接&#x1f516;预编译&#x1f516;编译&#x1f516;汇编&#x1f516;链接&#x1f516;符号表的作用 &#x1f4d6;执行环境…

外贸订单管理平台有哪些?

外贸订单的管理是外贸出口业务中非常重要的一项管理工作&#xff0c;订单能否实现准时交付则需要涉及到各种流程顺畅的支持。那么外贸订单管理平台有哪些&#xff1f;有孚盟软件。 首先&#xff0c;外贸订单管理平台主要是解决外贸公司的订单查询与管理&#xff0c;面对大量不…

2.4G无线收发芯片 XL2400,SOP8封装,外挂MCU使用

XL2400 芯片是工作在 2.400~2.483GHz 世界通用 ISM 频段的单片无线收发芯片。该芯片集成射频收发机、频率收生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带 ACK 的通信模式。发射输出率、工作频道以及通信数据率均可配置。芯片已将多颗外围贴片阻容…

mysql错误-1055 - Expression #1 of SELECT list is not in GROUP BY clause 解决方案

目录 业务场景发现问题表结构表数据sql查询 分析问题验证 解决问题方案一方案二方案三 注意事项 业务场景 当遇到数据库重复数据&#xff0c;就要将数据进行分组&#xff0c;取其中一条来展示&#xff0c;此时就要用到group by语句。 但当mysql的版本高于5.7时&#xff0c;在执…

ESP32设备驱动-TCA9548A-I2C多路复用器驱动

TCA9548A-I2C 多路复用器驱动 文章目录 TCA9548A-I2C 多路复用器驱动1、TCA9548A介绍2、硬件准备3、软件准备4、驱动实现4.1 TCA9548A总线复用实现4.2 驱动多个OLED显示屏4.3 驱动多个BME280传感器在本文中,将介绍如何使用 TCA9458A I2C 多路复用器扩展 I2C 总线端口。 如果你…

【Python 基础篇】Python 列表及列表常用函数

文章目录 一. 什么是列表二. 列表的创建和访问2.1 创建列表2.2 访问列表元素 三. 列表的操作3.1 修改列表元素3.2 列表的添加和删除元素3.2.1 添加元素3.2.2 删除元素 3.3 列表的排序3.4 判断元素是否在列表中 四. 列表的常用函数和方法五. 总结 一. 什么是列表 在Python中&am…