1、最简便的方法:使用 img 的 onerror 事件
https://www.jb51.net/article/8796.htm
正常显示前者,错误时显示后者
<img src="//www.jb51.net/logoddd.gif" onerror="javascript:this.src='//www.jb51.net/logos.gif'" />
上面的方法虽然简便,但也有一定的适用范围,对于前者不固定的情形就不适用了。
比如:用户登陆后,显示每一个用户的头像,此时每一个用户的头像文件名都是不同的。
这就需要一个函数来专门判定图片文件是否存在。
2、使用 onload 和 onerror 函数判定图片文件是否存在
https://segmentfault.com/q/1010000013876215
function CheckImgExists(imgurl) {
var ImgObj = new Image(); //判断图片是否存在
ImgObj.onload=function(){
console.log(ImgObj.width,ImgObj.height);
}
ImgObj.onerror=function(){
console.log('error');
}
ImgObj.src = imgurl;
}
上面的函数中有2个关键点:
(1)、图片加载是异步的--需要时间的,所以只能在 异步函数中 onload 和 onerror 来判断
(2)、onload 一定要放到给 src 赋值前面, 否则从缓存取过来是不一定会走到 onload
从上面函数的输出来看,的确能判断图片文件是否存在,但在真正的项目中,我们需要的是 onload 和 onerror 函数能返回一个布尔量 或者 其他的变量 来供另一个函数做判断,但是很遗憾,这两个函数中都不能返回任何值。
此时,Promise对象 就该出场了。参考文章:
3、onload 、onerror 结合 Promise 对象 判断图片文件是否存在
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise
对象。·
所谓Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
Promise
对象有以下两个特点。
(1)对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:Pending
(进行中)、Resolved
(已完成,又称Fulfilled)和Rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise
这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise
对象的状态改变,只有两种可能:从Pending
变为Resolved
和从Pending
变为Rejected
。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise
对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
========================
最简单的 Promise 使用 Demo:
1、创建 Promise实例
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
2、调用该实例的 then 方法并传入参数
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then
方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
本质上,就可以在 then
方法 中获得函数的返回值。
上面只是理论上的示例,下面是实际使用示例:
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
上面代码中,timeout
方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms
参数)以后,Promise实例的状态变为Resolved,就会触发then
方法绑定的回调函数。
===============================
下面是判断图片文件是否存在的实用代码:【可作为工具类方法放在 公共 JS 中】
1、定义一个函数,该函数返回一个 Promise 对象,并用变量接收该 Promise 对象
//判断图片是否存在
var CheckImgExists = function CheckImg(imgurl) {
return new Promise(function(resolve, reject) {
var ImgObj = new Image();
ImgObj.onload=function(){
// console.log(ImgObj.width+"==",ImgObj.height+"==");
resolve("load image success");
}
ImgObj.onerror=function(){
// console.log('error');
reject('Could not load image at ' + imgurl);
}
ImgObj.src = imgurl;
});
}
2、调用该 Promise 对象 的 then 方法 并给 函数 传入参数
//设置图片 动态传入 imgurl。若存在则显示该图片,不存在则显示默认图片
function setImage(imgurl){
//图片存在执行第一个函数,否则执行第二个函数
CheckImgExists(imgurl).then(function(json) {
$("#image").attr("src",imgurl);
console.log(json);
}, function(error) {
$("#image").attr("src",default-ImgPath);
console.error(error);
});
}