Come nascondere silenziosamente l'icona "Immagine non trovata" quando l'immagine sorgente src non viene trovata


91

Sai come nascondere la classica icona "Immagine non trovata" da una pagina HTML sottoposta a rendering quando un file immagine non viene trovato?

Qualche metodo di lavoro che utilizza JavaScript / jQuery / CSS?


La risposta di Andy è corretta, tuttavia, potresti voler utilizzare style.vsibility invece. Se imposti la visibilità, l'elemento mantiene comunque il suo spazio sul documento, quindi nessun movimento divertente del documento.
Christian

Non vedo il punto. Semplicemente non dovresti cercare di raggiungere nessuna risorsa esistente dal tuo codice html. Usare javascript per nascondere le risorse mal gestite sembra essere una brutta soluzione per me.
Boris Delormas

1
@Kaaviar Ti manca il punto. Ci sono molte immagini di hotlink interrotte qui su Stack Overflow a causa del fatto che le immagini possono essere disponibili al momento del post, ma non disponibili alcuni mesi dopo. Queste immagini sono silenziosamente e delicatamente nascoste.
systempuntoout

1
@systempuntoout: non sono sicuro del motivo per cui i due vengono trattati in modo diverso. Ho testato un'immagine non funzionante in Firefox e Chrome, non viene visualizzata in Firefox ma risulta danneggiata in Chrome. È chiaro che questo è qualcosa che Firefox sta decidendo da solo, poiché non sembra che nessuno stile lo stia influenzando. btw, ottimo lavoro su StackPrinter.
Andy E

2
@systempuntoout: ho scoperto qualche informazione in più su come funziona Firefox con questo. Vedi un violino aggiornato e la [pseudo-classe proprietaria, :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Prima stavo solo pensando tra me e me che una pseudo classe sarebbe stata utile per disegnare immagini spezzate.
Andy E

Risposte:


102

Puoi utilizzare l' onerrorevento in JavaScript per agire quando un'immagine non viene caricata:

var img = document.getElementById("myImg");
img.onerror = function () { 
    this.style.display = "none";
}

In jQuery (dato che hai chiesto):

$("#myImg").error(function () { 
    $(this).hide(); 
});

O per tutte le immagini:

$("img").error(function () { 
    $(this).hide();
    // or $(this).css({visibility:"hidden"}); 
});

Dovresti usare al visibility: hiddenposto di .hide()se nascondere le immagini potrebbe cambiare il layout. Molti siti sul Web utilizzano invece un'immagine predefinita "nessuna immagine", che punta l' srcattributo a quell'immagine quando la posizione dell'immagine specificata non è disponibile.


1
andy - quale sarebbe la soluzione "globale" da applicare a TUTTE le immagini? Penso che sarebbe abbastanza facile se fossero tutti nello stesso div - mi chiedevo solo TUTTE le immagini nel documento ...
jim tollan

@jAndy: ero abbastanza sicuro che lo fosse, ma il tuo commento mi ha fatto ricontrollare. Un rapido Google ha restituito questa pagina di w3schools (scusa David, se stai leggendo questo) indicando il supporto cross browser.
Andy E

2
@ jim: se stai usando jQuery, puoi applicare l'evento a tutte le immagini. basta usare il selettore di tag, ad es $("img").error(function () { /*...*/ });.
Andy E

@ Anddy E: suona bene, +1. la prossima domanda interessante sarebbe " error" è vincolabile con live()o delegate().
jAndy

3
visibilitysarebbe meglio, poiché displaypuò rompere il layout.
gblazex

114
<img onerror='this.style.display = "none"'>

Sfortunatamente non posso utilizzare questa soluzione perché il contenuto html viene scaricato da un sito Web di terze parti tramite Json e non posso modificarlo. Grazie comunque.
systempuntoout

9
Fantastico, proprio quello di cui avevo bisogno. Semplice e discreto, si inserisce in un modello!
Max

Anche se abbastanza vecchio, questo è fantastico! C'è un modo per nascondere anche i tag <a> che circondano la mia immagine ora nascosta?
SJDS

9

Ho leggermente modificato la soluzione suggerita da Gary Willoughby, perché mostra brevemente l'icona dell'immagine rotta. La mia soluzione:

    <img src="..." style="display: none" onload="this.style.display=''">

Nella mia soluzione l'immagine è inizialmente nascosta e viene mostrata solo quando viene caricata con successo. Ha uno svantaggio: gli utenti non vedranno le immagini caricate a metà. E se l'utente ha disabilitato JS, non vedrà mai alcuna immagine


1
... e gli utenti non vedranno nulla, se javascript è disabilitato!
yckart

4
@yckart Bene, se gli utenti hanno javascript disabilitato, le applicazioni web più utili non funzioneranno comunque ...
stupore

<img src="..." onerror="this.style.display = 'none'"/> potrebbe funzionare meglio per i casi di browser a metà caricamento e non js?

6

Per nascondere ogni errore di immagine, aggiungi questo JavaScript nella parte inferiore della pagina (appena prima del tag di chiusura del corpo):

(function() {
    var allimgs = document.images;
    for (var i = 0; i < allimgs.length; i++) {
        allimgs[i].onerror = function() {
            this.style.visibility = "hidden"; // Other elements aren't affected. 
        }
    }
})();

Questo è il mio approccio preferito perché praticamente garantisce che gli eventi onerror siano associati prima che le immagini abbiano un errore e non sia necessario aggiungere attributi onerror a ciascun tag immagine. Assicurati di inserire questo codice dopo tutti i tag immagine ma prima di qualsiasi altro javascript in <body>, altrimenti un caricamento JS esterno di blocco potrebbe causare l'esecuzione dopo un errore di immagine.
galati

Questo funziona per me, insieme al consiglio dei galati, ho bisogno di eseguire questo JS prima di qualsiasi cosa che possa ritardarlo.
Adamz

Questo risponde alla domanda originale, ma è un processo a senso unico. Per rendere nuovamente visibili le immagini che vengono caricate successivamente, aggiungi anche un evento onload. allimgs [i] .onload = function () {this.style.visibility = "visible"; };
TRT 1968

5

Potrebbe essere un po 'tardi per rispondere, ma ecco il mio tentativo. Quando ho riscontrato lo stesso problema, l'ho risolto utilizzando un div delle dimensioni dell'immagine e impostando l'immagine di sfondo su questo div. Se l'immagine non viene trovata, il div viene reso trasparente, quindi è tutto silenzioso senza codice java-script.


4

Facendo una rapida ricerca sulla risposta di Andy E , non è possibile live()vincolarla error.

// won't work (chrome 5)
$('img').live('error', function(){
     $(this).css('visibility', 'hidden');
});

Quindi devi andare come

$('<img/>', {
  src:    'http://www.notarget.com/fake.jpg',
  error:  function(e){
    $(this).css('visibility', 'hidden');
  }
}).appendTo(document.body);

vincolando direttamente la error event handlercreazione di un nuovo elemento.


2
+1, il motivo è che l' evento DOM onerror non fa bolle. live e delegare il lavoro posizionando il gestore di eventi più in alto nella gerarchia DOM e catturando l'evento mentre bolle. Ovviamente, gli sviluppatori di jQuery hanno risolto questo problema per alcuni eventi come focus e blur
Andy E

@ Anddy E: Sì, hanno già risolto il problema, potrebbe non essere la peggiore delle idee per cui fare una cosa simile error. Suona come un nice to haveper me.
jAndy

3

ho trovato un metodo ingegnoso per fare esattamente questo, pur essendo ancora funzionale quando si usa la ng-srcdirettiva in Angular.js e come ...

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='"
  />

è fondamentalmente una GIF trasparente più corta (come si vede http://proger.i-forge.net/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82% D0% B5% D1% 80 / [20121112]% 20Il% 20smallest% 20transparent% 20pixel.html )

ovviamente questa gif potrebbe essere tenuta all'interno di qualche variabile globale in modo da non rovinare i modelli.

<script>
  window.fallbackGif = "..."
</script>

e utilizzare

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src=fallbackGif"
  />

eccetera.


0

Basta usare semplici css

.AdminImageHolder {
display: inline-block;
min-width: 100px;
max-width: 100px;
min-height: 100px;
max-height: 100px;
background: url(img/100x100.png) no-repeat;
border: 1px solid #ccc;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.