2012-03-22 9 views
54

C'è un modo per determinare se un percorso immagine conduce a un'immagine reale, cioè rilevare quando un'immagine non riesce a caricare in Javascript.Rileva quando un'immagine non riesce a caricare in Javascript

Per un'applicazione Web, sto analizzando un file xml e creando dinamicamente immagini HTML da un elenco di percorsi immagine. Alcuni percorsi di immagine potrebbero non esistere più sul server, quindi voglio fallire con grazia rilevando quali immagini non riescono a caricare ed eliminare quell'elemento HTML img.

Nota Le soluzioni JQuery non possono essere utilizzate (il capo non desidera utilizzare JQuery, sì, so che non è necessario avviarlo). Conosco un modo in JQuery per rilevare quando viene caricata un'immagine, ma non se ha fallito.

Il mio codice per creare elementi img, ma come posso rilevare se il percorso img porta a un caricamento non riuscito dell'immagine?

var imgObj = new Image(); // document.createElement("img"); 
imgObj.src = src; 
+0

Questo potrebbe aiutare: http://stackoverflow.com/questions/1977871/check-if-an-image-is-loaded-no-errors -in-javascript (è jQuery, ma può ancora portarti sulla giusta strada) –

+0

prova uno di questi https://www.google.com/search?rlz=1C1CHJL_esMX444MX444&sourceid=chrome&ie=UTF-8&q=Detect+quando+ un + immagine + non riesce + a + carico + in + Javascript # hl = it & rlz = 1C1CHJL_esMX444MX444 & sclient = psy-ab & q = sito% 3Ahttp% 3A% 2F% 2Fstackoverflow.com + Rilevare + quando + un + immagine + non riesce + a + carico + in + Javascript & OQ = sito: http% 3A% 2F% 2Fstackoverflow.com + Rilevare + quando + un'immagine + + + non riesce a + carico + in + Javascript & aq = f & aqi = & AQL = & gs_l = serp.12 ...4485l10141l0l11322l11l9l0l0l0l0l165l703l8j1l9l0.frgbld. & PBX = 1 & BAV = on.2, or.r_gc.r_pw.r_qf., Cf.osb & fp = 19d0ebe5924d5495 & biw = 1024 & BiH = 653 – ajax333221

+1

divertente @ ajax333221 questa domanda è il primo nei risultati del tuo link :) –

risposta

63

Si potrebbe provare il seguente codice. Non posso garantire la compatibilità con il browser, quindi dovrai testarlo.

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"); 

E le mie simpatie per il capo jQuery-resistente!

+1

Qualsiasi idea se c'è un modo per dire se incontra un reindirizzamento? – quickshiftin

+2

Questo non funziona su webKit (Epiphany, Safari, ...) a seconda del server da cui stai ricevendo un'immagine. Ad esempio, a volte imgur non invia un'immagine esistente né uno stato 404 e l'evento di errore non viene attivato in questo caso. –

3

Ecco una funzione che ho scritto per un'altra risposta: Javascript Image Url Verify. Non so se è esattamente ciò di cui hai bisogno, ma utilizza le varie tecniche che utilizzeresti quali gestori per onload, onerror, onabort e un timeout generale.

Poiché il caricamento dell'immagine è asincrono, si chiama questa funzione con l'immagine e quindi chiama il callback più tardi con il risultato.

-14

proprio come di seguito:

var img = new Image(); 
img.src = imgUrl; 

if (!img.complete) { 

//has picture 
} 
else //not{ 

} 
+3

No. Questo potrebbe indurti a vedere se l'immagine è memorizzata nella cache, in alcuni browser - ma senza un richiamo del caricamento, non ti aspetti nemmeno un momento per dare al browser la possibilità di avviare una richiesta HTTP per quell'immagine. – ChaseMoskal

+0

questo è solo per dire qualcosa! – Hitmands

+2

Il caricamento dell'immagine è asincrono. –

19

La risposta è bello, ma introduce un problema. Ogni volta che si assegna direttamente onload o onerror, è possibile sostituire la richiamata che è stata assegnata in precedenza. Ecco perché c'è un buon metodo che "registra il listener specificato sul EventTarget chiamato" come si dice su MDN. Puoi registrare quanti più ascoltatori vuoi sullo stesso evento.

Lasciatemi riscrivere la risposta un po '.

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"); 

Poiché il processo di risorsa carico esterno è asincrona, sarebbe ancora più bello da usare JavaScript moderna con promesse, come quelli che seguono.

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'); 
    } 

); 
+0

forse mi manca qualcosa, ma come può il compito (tester.onload = ..) sostituire un callback, se il "tester" è stato appena creato? anche se parte oscura del codice aggiunge un evento a ogni immagine creata, non è ovvio che vogliamo mantenere quegli eventi allo scopo di rilevare se esiste un'immagine. – jvilhena

+0

Hai assolutamente ragione. In questo caso particolare potrebbe non essere un problema perché è altamente probabile che non verrà sostituito. Tuttavia, in generale, aggiungere un listener di eventi è una procedura migliore dell'assegnazione diretta di un metodo. –

+0

JavaScript moderno senza funzioni di freccia e async/attende? :) –

2
/** 
* 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; 
}); 
0

questo:

<img onerror="this.src='/images/image.png'" src="..."> 
+1

Sebbene questo sia un utile attributo che può essere usato come tecnica di failover dell'immagine, una risposta più prolissa sarebbe utile per i lettori per capirlo. – sorak

Problemi correlati