Detectați când o imagine nu se încarcă în JavaScript
Există o modalitate de a determina dacă un cale de imagine duce la o imagine reală, adică să detectăm când o imagine nu reușește să se încarce în JavaScript.
Pentru o aplicație web, analizez un fișier XML și creez dinamic imagini HTML dintr-o listă de căi de imagini. Unele căi de imagini s-ar putea să nu mai existe pe server, așa că vreau să eșuez în mod elegant detectând care imagini nu reușesc să se încarce și ștergând acel element HTML img.
Rețineți că soluțiile jQuery nu vor putea fi utilizate (șeful nu vrea să folosească jQuery, da, știu, nu mă porniți pe acest subiect). Știu o metodă în jQuery pentru a detecta când o imagine s-a încărcat, dar nu și dacă a eșuat.
Codul meu creează elemente img, dar cum pot detecta dacă calea img duce la o imagine care nu s-a putut încărca?
var imgObj = new Image(); // document.createElement("img");
imgObj.src = src;
Răspuns #1
Ai putea încerca următorul cod. Nu pot garanta compatibilitatea cu browserele, așa că va trebui să testezi asta.
function testImage(URL) {
var tester=new Image();
tester.onload=imageFound;
tester.onerror=imageNotFound;
tester.src=URL;
}
function imageFound() {
alert('That image is found and loaded');
}
function imageNotFound() {
alert('That image was not found.');
}
testImage("http://foo.com/bar.jpg");
Și simpatia mea pentru șeful care rezistă la jQuery!
Răspuns #2
Răspunsul este bun, dar introduce o problemă. Ori de câte ori atribuiți direct onload sau onerror, acest lucru poate înlocui callback-ul care a fost atribuit anterior. De aceea există o metodă utilă care „registrează listener-ul specificat pe EventTarget pe care este apelat”, așa cum se spune pe MDN. Puteți înregistra câți listeneri doriți pe același eveniment.
Lasă-mă să rescriu puțin răspunsul.
function testImage(url) {
var tester = new Image();
tester.addEventListener('load', imageFound);
tester.addEventListener('error', imageNotFound);
tester.src = url;
}
function imageFound() {
alert('That image is found and loaded');
}
function imageNotFound() {
alert('That image was not found.');
}
testImage("http://foo.com/bar.jpg");
Deoarece procesul de încărcare a resurselor externe este asincron, ar fi chiar mai plăcut să folosești JavaScript modern cu promisiuni, cum ar fi următorul exemplu.
function testImage(url) {
// Define the promise
const imgPromise = new Promise(function imgPromise(resolve, reject) {
// Create the image
const imgElement = new Image();
// When image is loaded, resolve the promise
imgElement.addEventListener('load', function imgOnLoad() {
resolve(this);
});
// When there's an error during load, reject the promise
imgElement.addEventListener('error', function imgOnError() {
reject();
})
// Assign URL
imgElement.src = url;
});
return imgPromise;
}
testImage("http://foo.com/bar.jpg").then(
function fulfilled(img) {
console.log('That image is found and loaded', img);
},
function rejected() {
console.log('That image was not found');
}
);
Răspunsul #3
Acesta :
<img onerror="this.src='/images/image.png'" src="...">
Răspunsul #4
/**
* Tests image load.
* @param {String} url
* @returns {Promise}
*/
function testImageUrl(url) {
return new Promise(function(resolve, reject) {
var image = new Image();
image.addEventListener('load', resolve);
image.addEventListener('error', reject);
image.src = url;
});
}
return testImageUrl(imageUrl).then(function imageLoaded(e) {
return imageUrl;
})
.catch(function imageFailed(e) {
return defaultImageUrl;
});
