Upptäck när en bild inte laddas i JavaScript
Finns det ett sätt att avgöra om en bildväg leder till en faktisk bild, det vill säga, att upptäcka när en bild inte kan laddas i JavaScript.
För en webbapp analyserar jag en XML-fil och skapar dynamiskt HTML-bilder från en lista med bildvägar. Vissa bildvägar kanske inte längre finns på servern, så jag vill hantera fel på ett bra sätt genom att upptäcka vilka bilder som inte laddas och ta bort det HTML img-elementet.
Observera att jQuery-lösningar inte kommer att kunna användas (chefen vill inte använda jQuery, ja jag vet, börja inte med mig om det). Jag känner till ett sätt i jQuery för att upptäcka när en bild har laddats, men inte om den misslyckades.
Min kod för att skapa img-element, men hur kan jag upptäcka om img-sökvägen leder till en bild som inte kunde laddas?
var imgObj = new Image(); // document.createElement("img");
imgObj.src = src;
Svar #1
Du kan prova följande kod. Jag kan dock inte garantera webbläsarkompatibilitet, så du måste testa det själv.
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");
Och mitt deltagande för chefen som är motståndare till jQuery!
Svar #2
Svaret är bra, men det introducerar ett problem. När du tilldelar onload eller onerror direkt kan det ersätta den callback som tilldelades tidigare. Det är därför det finns en bra metod som "registrerar den angivna lyssnaren på den EventTarget den anropas på" som de säger på MDN. Du kan registrera så många lyssnare du vill på samma händelse.
Låt mig skriva om svaret lite grann.
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");
Eftersom processen för att ladda externa resurser är asynkron skulle det vara ännu trevligare att använda modern JavaScript med promises, såsom följande.
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');
}
);
Svar #3
Det här :
<img onerror="this.src='/images/image.png'" src="...">
Svar #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;
});
