Jak po cichu ukryć ikonę „Nie znaleziono obrazu”, gdy nie znaleziono źródłowego obrazu źródłowego

91

Czy wiesz, jak ukryć klasyczną ikonę „Nie znaleziono obrazu” na renderowanej stronie HTML, gdy plik obrazu nie został znaleziony?

Jakaś metoda pracy wykorzystująca JavaScript / jQuery / CSS?

systempuntoout
źródło
Odpowiedź Andy'ego jest poprawna, jednak zamiast tego możesz użyć style.vsibility. Jeśli ustawisz widoczność, element nadal zachowuje swoją przestrzeń w dokumencie, dzięki czemu nie ma śmiesznych ruchów dokumentu.
Christian,
Nie widzę sensu. Po prostu nie powinieneś próbować dotrzeć do żadnych istniejących zasobów z kodu HTML. Używanie javascript do ukrywania źle rozdanych zasobów wydaje mi się brzydkim rozwiązaniem.
Boris Delormas
1
@Kaaviar Brakuje Ci sensu. W Stack Overflow jest wiele obrazków z linkami hotlinkami, ponieważ obrazy mogą być dostępne w momencie publikacji posta, ale niedostępne kilka miesięcy później. Te obrazy są cicho i delikatnie ukryte.
systempuntoout
1
@systempuntoout: Nie jestem pewien, dlaczego są traktowani inaczej. Przetestowałem uszkodzony obraz w Firefoksie i Chrome, nie wyświetla się w Firefoksie, ale pokazuje się jako uszkodzony w Chrome. Oczywiste jest, że jest to coś, o czym Firefox decyduje sam, ponieważ nie wydaje się, aby jakikolwiek styl miał na to wpływ. btw, świetna robota na StackPrinter.
Andy E,
2
@systempuntoout: Dowiedziałem się trochę więcej informacji o tym, jak Firefox działa z tym. Zobacz zaktualizowane skrzypce i [zastrzeżoną pseudoklasę :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Pomyślałem sobie wcześniej, że pseudoklasa przyda się do stylizacji uszkodzonych obrazów.
Andy E,

Odpowiedzi:

102

Możesz użyć onerrorzdarzenia w JavaScript, aby działać, gdy obraz się nie ładuje:

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

W jQuery (skoro pytałeś):

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

Lub dla wszystkich obrazów:

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

Należy używać visibility: hiddenzamiast, .hide()jeśli ukrycie obrazów może zmienić układ. Wiele witryn internetowych używa zamiast tego domyślnego obrazu „bez obrazu”, wskazując srcatrybut na ten obraz, gdy określona lokalizacja obrazu jest niedostępna.

Andy E.
źródło
1
andy - jakie byłoby „globalne” rozwiązanie zastosowane do WSZYSTKICH obrazów? Myślę, że byłoby łatwo, gdyby wszystkie znajdowały się w tym samym div - po prostu zastanawiałem się nad WSZYSTKIMI obrazami w dokumencie ...
jim tollan
@jAndy: Byłem całkiem pewien, że tak, ale Twój komentarz sprawił, że sprawdziłem dwukrotnie. Szybki Google zwrócił tę stronę w3schools (przepraszam, David, jeśli to czytasz), wskazując na obsługę wielu przeglądarek.
Andy E,
2
@jim: Jeśli używasz jQuery, możesz zastosować zdarzenie do wszystkich obrazów. po prostu użyj selektora tagów, np $("img").error(function () { /*...*/ });.
Andy E,
@Andy E: brzmi dobrze, +1. następnym interesującym pytaniem byłoby, czy można " error" powiązać z live()lub delegate().
jAndy
3
visibilitybyłoby lepiej, ponieważ displaymoże zepsuć układ.
gblazex
114
<img onerror='this.style.display = "none"'>
Gary Willoughby
źródło
Niestety nie mogę skorzystać z tego rozwiązania, ponieważ zawartość html jest pobierana z witryny innej firmy za pośrednictwem Json i nie mogę jej edytować. W każdym razie dzięki.
systempuntoout
9
Niesamowite, właśnie to, czego potrzebowałem. Prosty i nie przeszkadzający, mieści się w szablonie!
Maksymalnie
Choć już dość stary, to jest świetne! Czy istnieje sposób na ukrycie tagów <a> otaczających mój teraz ukryty obraz?
SJDS
9

Nieznacznie zmodyfikowałem rozwiązanie zaproponowane przez Gary'ego Willoughby'ego, ponieważ na krótko pokazuje zepsutą ikonę obrazu. Moje rozwiązanie:

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

W moim rozwiązaniu obraz jest początkowo ukryty i jest wyświetlany tylko po pomyślnym załadowaniu. Ma tę wadę: użytkownicy nie zobaczą w połowie załadowanych obrazów. A jeśli użytkownik wyłączył JS, nigdy nie zobaczy żadnych obrazów

Szarfa
źródło
1
... a użytkownicy nic nie zobaczą, jeśli javascript jest wyłączony!
yckart
4
@yckart Cóż, jeśli użytkownicy mają wyłączony javascript, najbardziej przydatne aplikacje internetowe i tak nie będą działać ...
awe
<img src="..." onerror="this.style.display = 'none'"/>może działać lepiej w przypadku przeglądarek w połowie załadowanych i innych niż js?
6

Aby ukryć każdy błąd obrazu, po prostu dodaj ten JavaScript u dołu strony (tuż przed zamykającym tagiem body):

(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. 
        }
    }
})();
Q_Mlilo
źródło
Jest to moje preferowane podejście, ponieważ zapewnia prawie, że zdarzenia onerror są wiązane, zanim obrazy ulegną awarii i nie musisz dodawać atrybutów onerror do każdego znacznika obrazu. Pamiętaj, aby umieścić ten kod po wszystkich tagach obrazu, ale przed jakimkolwiek innym kodem JavaScript znajdującym się w <body>, w przeciwnym razie blokowanie zewnętrznego ładowania JS może spowodować wykonanie po błędzie obrazu.
galatians
Ten działa dla mnie, wraz z radami galatów, musisz mieć ten JS wykonany przed czymkolwiek, co mogłoby go opóźnić.
Adamz
To odpowiada na pierwotne pytanie, ale jest to proces jednokierunkowy. Aby obrazy, które następnie ładowały się, były ponownie widoczne, dodaj również zdarzenie onload. allimgs [i] .onload = function () {this.style.visibility = "widoczne"; };
TRT 1968
5

Odpowiedź może być trochę za późno, ale oto moja próba. Kiedy napotkałem ten sam problem, naprawiłem go, używając elementu div o rozmiarze obrazu i ustawiając obraz tła dla tego elementu div. Jeśli obraz nie zostanie znaleziony, element div jest renderowany jako przezroczysty, więc wszystko odbywa się cicho bez kodu skryptu java.

Adway Lele
źródło
4

Robiąc szybkie badanie odpowiedzi Andy'ego E , nie można go live()powiązać error.

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

Więc musisz iść jak

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

bezpośrednio wiążąc się error event handlerz tworzeniem nowego elementu.

jAndy
źródło
2
+1, powodem tego jest to, że zdarzenie onerror DOM nie pojawia się. na żywo i deleguj pracę, umieszczając program obsługi zdarzeń wyżej w hierarchii DOM i przechwytując zdarzenie w miarę jego wzrostu. Oczywiście twórcy jQuery pracowali nad tym przy niektórych wydarzeniach, takich jak skupienie i rozmycie
Andy E
@Andy E: Tak, już to obejść, może nie być najgorszym pomysłem, dla którego można zrobić coś podobnego error. Brzmi jak nice to havedla mnie.
jAndy
3

Znalazłem sprytną metodę, aby to zrobić, będąc nadal funkcjonalnym, gdy używam ng-srcdyrektywy w Angular.js i tak jak ...

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

jest to w zasadzie najkrótszy przezroczysty GIF (jak widać http://proger.i-forge.net/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82% D0% B5% D1% 80 / [20121112]% 20The% 20smallest% 20transparent% 20pixel.html )

oczywiście ten gif może być przechowywany w jakiejś zmiennej globalnej, więc nie zepsuje szablonów.

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

I użyć

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

itp.

Jacek Głodek
źródło
0

Po prostu użyj prostego 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;
}
Owais Bin Rizwan
źródło