在做项目过程中遇到图片请求失败的时候,图片区域会出现一个原生的碎片图标,非常影响用户体验。这时需要用一个 broken 的图片去代替它,来提升户体验。要做到这一点,首先要在代码中识别图片加载失败这个事情。那么怎么判断一个图片加载失败了呢?
在 js 中使用 onerror 事件
javascript 给我们提供了一个 onerror 事件,img 标签支持该事件,当装载文档或者图像的过程中发生了错误,就会触发 onerror 事件。
我们可以在这个事件中,定义要替换加载不出来的原图的 broken 图片。
核心代码:
| 1 | // html | 
注意:
如果 onerror 指定的图片也不存在的话,会出现无限死循环 404. 解决办法是在 js 中添加:
2
3
4
5
myfunction() {
this.src="./default.png";
this.onerror = null; // 添加这个防止默认图片也不存在而陷入死循环
}
在 Vue 中怎么使用 onerror
| 1 | // vue | 
番外
有时因为网络比较卡的原因需要多加载几次再判定为是否加载失败。
但是有时是因为网络连接断开而加载失败,需要在网络恢复连接时自动加载图片。
这是就需要知道,js中怎么识别网络断开和连接的,有两个事件:online 和 offline。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52var isOnLine = true;
var eventList = {};
window.addEventListener('offline', function() {
	isOnLine = false;
})
window.addEventListener('online', function() {
	if(!isOnline) {
		isOnLine = true;
		reLine(); // 执行重连后要做的事情 
	}
})
function reLine() {
	for(var key in eventList) {
		if(!eventList[key]) continue;
		var arg = eventList[key].arg;
		var thisOnFn = eventList[key].that;
		eventList[key].fun.apply(thisOnFn, arg);
		eventList[key] = null;
	}
}
function offLined(fun, arg, that) {
	if(!isOnLine) {
		var name = fun.name || '__new';
		eventList[name] = {};
		eventList[name].fun = fun;
		eventList[name].arg = [].slice.call(arg);
		eventList[name].that = that;
		return true;
	}
	return false;
}
---
// 重新定义myfunction
myfunction(imgObj, imgSrc, maxErrorNum) {
	if(offLined(restImgUrl, arguments, this)) return;
	if(maxErrorNum > 0) {
		imgObj.onerror = function () {
			myFunction(imgObj, imgSrc, maxErrorNum - 1)
		}
		setTimeout(function() {
			imgObj.src = imgSrc;
		}, 500)
	} else {
		imgObj.src = './default.png';
		this.onerror = null;
	} 
}
// 调用
<img src="img.png" onerror="myfunction(this, this.src, 3)">