我有一些应在其中某些页面设置图像的应用程序。这些图像在服务器上,每个图像都附加了唯一的ID。这是图像名称的示例:
AA_image1.jpg
AB_image1.jpg
AC_image1.jpg
AD_image1.jpg
AE_image1.jpg
我看到了以前的开发人员做了什么,以及他们如何检查图像的存在。他们使用了具有ID和图片名称的JSON文件。这是该代码的示例:
var images = [{
"id": "AA",
"image": "AA_image1.jpg"
},
{
"id": "AB",
"image": "AB_image1.jpg"
},
{
"id": "AC",
"image": "AC_image1.jpg"
},
{
"id": "AD",
"image": "AD_image1.jpg"
},
{
"id": "AE",
"image": "AE_image1.jpg"
}
];
var imgID = "AC";
var imgPrimary = "AC_image1.jpg";
var found = false;
var imgDefault = "default.jpg";
for (i = 1; i < images.length; i++) {
if (images[i].id == imgID && (images[i].image).toLowerCase() == (imgID + '_image1.jpg').toLowerCase()) {
found = true;
break;
}
}
if (found === true) {
console.log(imgPrimary);
} else {
console.log(imgDefault);
}
上面的示例似乎非常简单,但是我担心的是,如果图像从文件夹中删除并且JSON文件未更新?在这种情况下,我们将加载不存在的图像而不是默认图像。我想知道这种方法是否会更好:
var imgID = "AC";
var imgNames = [imgID + '_image1','default'];
var imgResults = {};
for(var i = 0; i < imgNames.length; i++){
checkImage( imgNames[i] );
}
function checkImage( imgName, keyName ) {
$.ajax({
type: "GET",
async: true,
url: "images/"+imgName+".jpg",
}).done(function(message,text,jqXHR){
imgResults[imgName] = true;
}).fail(function(jqXHR, textStatus, errorThrown){
imgResults[imgName] = false;
});
}
以下是imgResults
在流程完成后的示例:
console.log(imgResults);
控制台结果:
{
"default": true,
"AG_image1": false
}
我在第二个示例中遇到的唯一问题是,如果我尝试根据键检查结果,那么我将变得不确定。这是示例:
console.log(imgResults["AG_image1"]);
这是控制台中的结果:
undefined
我不确定这两者之间哪个更好,更安全。如果有人有建议,请告诉我。
答案 0 :(得分:3)
这可能是处理JS中丢失图像的最短代码。 imagePad
是对要在其中显示图像的DOM元素的引用。
var img = new Image();
img.addEventListener('error', function (e) {
// Image not found, show the default
this.src = iconBase + 'gen.png';
});
img.addEventListener('load', function () {
imagePad.appendChild(img);
}
img.src = 'the_given_src';
答案 1 :(得分:1)
尝试时无法搜索imgResults
对象的原因是因为AJAX请求是异步的,并且当您尝试访问结果时请求尚未完成。您需要等待请求完成才能继续。
console.log
显示结果的原因是因为console.log
是惰性的,并且直到您在开发工具中对其进行扩展之前都不会评估该对象,console.dir
将向您显示一个空对象那一点。
此外,由于您有多个请求要等待,因此您将要创建一个Promise数组,其中每个Promise对应于每个请求的负载/失败,然后使用Promise.all
等待在完成结果之前完成所有承诺。
要验证资源是否存在,可以使用HEAD
请求而不是GET
请求,以防止无故加载整个图像。也不需要依赖诸如jQuery之类的大型库来处理AJAX请求,因为在当今时代,XMLHttpRequest得到了很好的支持。
class ResourceValidator extends EventTarget {
constructor(target) {
super()
this.target = target
this._ready = false
this._valid = false
this.validate()
}
validate() {
const request = new XMLHttpRequest()
request.addEventListener('load', event => {
this._ready = true
this._valid = true
this.dispatchEvent(new Event('ready'))
})
request.addEventListener('error', event => {
this._ready = true
this.dispatchEvent(new Event('ready'))
})
request.open('HEAD', this.target)
request.send()
}
get ready() {
return new Promise(resolve => {
if(this._ready === true) resolve(true)
else this.addEventListener('ready', _ => resolve(true))
})
}
get valid() {
return new Promise(resolve => {
if(this._ready === true) resolve(this._valid)
else this.addEventListener('ready', _ => resolve(this._valid))
})
}
}
async function validateImageSources(sources) {
const results = {}
const promises = []
for(let source of sources) {
const validator = new ResourceValidator(source)
const promise = validator.valid
promise.then(valid => results[source] = valid)
promises.push(promise)
}
await Promise.all(promises)
return results
}
validateImageSources([
'https://picsum.photos/200',
'https://nosuchaddress.io/image.png'
]).then(results => {
console.log(results)
console.log(results['https://picsum.photos/200'])
})