2009-05-04 9 views
54

In IE können Sie den Status "readystate" ändern. Es gibt Onload, aber ich lese scary things. jQuery schließt das Ladeereignis des DOM recht gut mit "ready" ab. Es scheint wahrscheinlich, dass ich nur eine andere nette Bibliothek der Implementierung von Image Loading ignoriere.Browserunabhängige Erkennung, wenn das Image geladen wurde

Der Kontext ist, dass ich Bilder dynamisch (über Server-Callbacks) erzeuge, die einige Zeit dauern können Download. In meinem IE-only-Code setze ich den src des img-Elements, und wenn das onreadystatechange-Ereignis mit dem Status "complete" ausgelöst wird, füge ich es dem DOM hinzu, damit der Benutzer es sieht.

Ich wäre glücklich mit einer "nativen" JavaScript-Lösung oder einem Zeiger auf eine Bibliothek, die die Arbeit erledigt. Es gibt so viele Bibliotheken da draußen, und ich bin mir sicher, dass dies ein Fall ist, in dem ich einfach nicht über den richtigen Bescheid weiß. Das heißt, wir sind bereits jQuery-Benutzer, also bin ich nicht begierig, eine sehr große Bibliothek hinzuzufügen, nur um diese Funktionalität zu bekommen.

+0

Ich verstehe nicht vollständig - wollen Sie eine einzige reine JS-Lösung für die Erkennung, wenn ein Bild geladen wurde, oder suchen Sie eine alternative Bibliothek zu jQuery für die Erkennung, wenn ein Bild geladen wurde? –

+0

Ich wäre mit beiden glücklich. Ich würde jQuery nicht vernachlässigen, wie ich es anderswo verwende; Ich drücke nur meinen Verdacht aus, dass dies ein gut gelöstes Problem in einer Bibliothek ist, mit der ich nicht vertraut bin. –

+0

Vergiss nicht, uns mitzuteilen, was du tust! –

Antwort

46

HINWEIS: Ich schrieb dies im Jahr 2010, die Browser in der Wildnis waren IE 8/9 Beta, Firefox 3.x und Chrome 4.x. Bitte verwenden Sie dies nur für Forschungszwecke. Ich bezweifle, dass Sie dies in einen modernen Browser kopieren und ohne Probleme ausführen können.

WARNUNG: Es ist 2017 jetzt bekomme ich noch hin und wieder Punkte, bitte nur für Forschungszwecke verwenden. Ich habe derzeit keine Ahnung, wie ich den Ladezustand von Bildern erkennen kann, aber es gibt wahrscheinlich weitaus elegantere Möglichkeiten, dies zu tun ... zumindest hoffe ich ernsthaft darauf. Ich empfehle dringend, meinen Code in einer Produktionsumgebung nicht mehr zu verwenden.


Ich bin ein bisschen spät zu dieser Partei, vielleicht diese Antwort jemand anderes helfen ...

Wenn Sie jQuery verwenden mit den Aktien Event-Handler nicht stören (Onclick/Onmouseover/etc), höre eigentlich auf, sie ganz zu benutzen. Verwenden Sie die Ereignismethoden, die sie in ihrem API bereitgestellt haben.


Dies wird alarmieren, bevor das Bild an den Körper angehängt wird, weil Load-Ereignis ausgelöst wird, wenn das Bild in den Speicher geladen wird. Es macht genau das, was Sie ihm sagen: Erstellen Sie ein Bild mit dem src von test.jpg, wenn test.jpg lädt eine Warnung, dann an den Körper anhängen.

var img = $('<img src="test.jpg" />'); 
img.load(function() { 
    alert('Image Loaded'); 
}); 
$('body').append(img); 

Dies wird alarmiert, nachdem das Bild in den Körper eingeführt wird, wieder, zu tun, was Sie ihm gesagt: ein Bild zu erstellen, ein Ereignis gesetzt (keinen src Satz, so dass es nicht geladen ist), füge das Bild an den Körper an (immer noch kein src), setze jetzt den src ... jetzt wird das Bild geladen, so dass das Ereignis ausgelöst wird.

var img = $('<img />'); 
img.load(function() { 
    alert('Image Loaded'); 
}); 
$('body').append(img); 
$img.attr('src','test.jpg'); 

Sie können natürlich auch einen Fehlerhandler hinzufügen und eine Reihe von Veranstaltungen mit bind() fusionieren.

var img = $('<img />'); 
img.bind({ 
    load: function() { 
     alert('Image loaded.'); 
    }, 
    error: function() { 
     alert('Error thrown, image didn\'t load, probably a 404.'); 
    } 
}); 
$('body').append(img); 
img.attr('src','test.jpg'); 

Per Antrag von @ChrisKempen ...

ist hier eine nicht-ereignisgesteuerte Art und Weise zu bestimmen, ob die Bilder aufgebrochen werden, nachdem das DOM geladen wird. Dieser Code ist eine Ableitung von Code aus einem Artikel von StereoChrome, der mit den Attributen naturalWidth, naturalHeight und complete ermittelt, ob das Bild vorhanden ist.

$('img').each(function() { 
    if (this.naturalWidth === 0 || this.naturalHeight === 0 || this.complete === false) { 
     alert('broken image'); 
    } 
}); 
+12

WARNUNG: Von den jQuery-Dokumenten: Einschränkungen des Ladeereignisses bei Verwendung von Bildern: Eine häufige Herausforderung, die Entwickler mithilfe der Verknüpfung .load() zu lösen versuchen, besteht darin, eine Funktion auszuführen, wenn ein Bild (oder eine Sammlung von Bildern) vollständig vorhanden ist geladen. Es gibt mehrere bekannte Vorbehalte, die beachtet werden sollten. Diese sind: Es funktioniert nicht konsistent noch zuverlässig cross-browser Es wird nicht korrekt in WebKit ausgelöst, wenn das Bild src auf die gleichen src wie zuvor festgelegt ist Es nicht korrekt Blase den DOM-Baum Can feuern für Bilder ab, die bereits im Cache des Browsers gespeichert sind – Ben

+0

Ausgezeichneter Punkt @Ben. – paulj

+1

Ich bin noch später auf die Party, aber was ist, wenn die Bilder schon hinzugefügt wurden und du überprüfen musst, ob sie geladen wurden? Danke für irgendwelche Gedanken/Vorschläge! :) –

1

Wenn im nicht irrt in Javascript einen Image-Tag die Ereignisse hat onload und onerror

hier ist ein interessantes Stück Code i gebrochene Bilder zu verstecken tat

in einem Stil-Tag

img.failed{ 
    display:none; 
} 

mit der img onerror ich hatte ein Stück von Javascript, das that.className = fehlgeschlagen und es würde das Bild ausblenden, wenn es fehlerhaft

kann jedoch habe ich falsch verstanden, was Ihr Ziel

+1

Obwohl einige Browser dies unterstützen, wird das "onload" -Ereignis nicht von der W3C-Standard und damit nicht alle Browser müssen oder müssen dies unterstützen. –

5

Die einzige zuverlässige Weise, die ich gefunden habe, ist alles auf der Client-Seite, wie dies zu tun ...

var img = new Image(); 
img.onload = function() { 
    alert('Done!'); 
} 
img.src = '/images/myImage.jpg'; 
+1

Obwohl einige Browser dies unterstützen, wird das "onload" -Ereignis vom W3C-Standard nicht unterstützt und daher müssen nicht alle Browser dies unterstützen. –

3

Ich denke, onload sollte gut funktionieren. Müssen Sie das Markup für die Bilder generieren oder können Sie sie statisch hinzufügen? Wenn letzteres, würde ich vorschlagen, die folgende:

<img src="foo.png" class="classNeededToHideImage" onload="makeVisible(this)"> 

Alternativ können Sie window.onload verwenden, um alle Bilder auf einmal sichtbar zu machen - window.onload ausgelöst, nachdem alle externen Ressourcen Laden beendet haben.

Wenn Sie die Bilder dynamisch hinzufügen möchten, müssen Sie zuerst warten, bis das DOM bereit ist, geändert zu werden, dh jQuery verwenden oder Ihren eigenen DOMContentLoaded-Hack für Browser implementieren, die es nicht nativ unterstützen.

Dann erstellen Sie Ihre Bildobjekte, weisen Sie onload Listener zu, um sie sichtbar zu machen und/oder sie dem Dokument hinzuzufügen.

Noch besser (aber etwas komplizierter) wäre es, die Bilder sofort zu erstellen und zu starten, wenn das Skript ausgeführt wird. Bei DOMContentLoaded müssen Sie jedes Bild auf complete überprüfen, um zu entscheiden, ob Sie sie sofort zum Dokument hinzufügen oder auf den onload Listener des Bildes warten.

+1

Obwohl einige Browser dies unterstützen, wird das "onload" -Ereignis vom W3C-Standard nicht unterstützt und daher müssen nicht alle Browser dies unterstützen. –

+0

Nun, wenn "ein paar Browser" scheint jeder Mainstream-Browser sinde NN4 zu sein, ist es ziemlich sicher anzunehmen, dass die Funktion wird nicht bald weggehen. So traurig es auch sein mag, die W3C-Spezifikationen spiegeln selten die Realität wider, mit der Webentwickler konfrontiert sind ... – Christoph

+0

Noch einmal, ich bin mir dessen bewusst, aber es ist immer gut zu bemerken, was die Spezifikationen aussagen, wenn aus keinem anderen Grund genau das zu verstehen ist weisen Sie darauf hin - dass sie nicht mit der Realität in Berührung kommen und aktualisiert werden müssen. Übrigens, was ist "js-hacks" und warum wird es benötigt? Ich habe von Ihrem Profil bemerkt, dass Sie es erstellt haben, aber es ist schwierig herauszufinden, was es ist, da Ihre Website keine Informationen enthält und ich keine Zeit habe, alle Dateien zu lesen, die genau danach suchen. –

10

According to the W3C spec, nur Die BODY- und FRAMESET-Elemente bieten ein "onload" -Ereignis zum Anhängen an. Einige Browser unterstützen es unabhängig, aber beachten Sie, dass es nicht erforderlich ist, die W3C-Spezifikation zu implementieren.

Etwas, das für diese Diskussion relevant sein könnte, wenn auch nicht unbedingt die Antwort, die Sie benötigen, sind, ist diese Diskussion:

Image.onload event does not fire on Internet Explorer when image is in cache


Etwas anderes, dass sein kann Verwandte auf Ihre Bedürfnisse, obwohl es möglicherweise nicht, ist diese Info über die Unterstützung einer synthetisierten "Onload" -Ereignis für alle dynamisch geladenen DOM-Element:

How can I determine if a dynamically-created DOM element has been added to the DOM?

+0

das ist vielleicht wahr, aber onload für Bilder ist ein De-facto-Standard (seit Netscape Navigator 4 verfügbar) – Christoph

+0

Sicher, ich habe nie gesagt, dass es nicht etwas ist, auf das er zählen könnte, einfach dafür sorgen, dass er sich dessen bewusst ist spec - ignorieren Sie die Spezifikationen auf eigene Gefahr. –

+0

Das Problem mit Image.onload, das Sie erwähnen, ist GWT-spezifisch - siehe http://code.google.com/p/google-web-toolkit/issues/detail?id=863#c5; Image.onload muss vor Image.src gesetzt werden, um dies zu vermeiden, was bereits implizit von Josh – Christoph

1

Es wäre die Antwort erscheinen ist die Verwendung onreadystatechange in IE und onLoad in anderen Browsern. Wenn keiner verfügbar ist, etwas anderes tun. onLoad wäre vorzuziehen, aber IE löst es nicht aus, wenn ein Bild aus dem Cache geladen wird, wie in einer der Antworten unten angegeben.

+0

IE feuert onload beim Laden aus dem Cache - Sie müssen nur sicherstellen, "onload" zu setzen, bevor Sie 'src' setzen; Das Problem, das Jason erwähnt, ist GWT-spezifisch, was auf der verlinkten Seite erwähnt wird. – Christoph

+0

Es scheint so, als hättest du recht - danke, dass du bis zum Ende der Kommentarkette tiefer getaucht bist. Jetzt muss ich es testen ... –

3

Okay, ich werde versuchen, die verschiedenen Teilantworten hier (einschließlich meiner) zusammenzufassen.

Es scheint die Antwort zu sein, onload zu verwenden, das "weithin unterstützt" ist, obwohl nicht offiziell gemäß Standards verlangt wird. Beachten Sie, dass Sie insbesondere für den IE onLoad setzen müssen, bevor Sie das Attribut src setzen, oder dass es beim Laden eines Images aus dem Cache nicht onload auslöst. Dies scheint auf jeden Fall die beste Vorgehensweise zu sein: Richten Sie Ihre Ereignishandler ein, bevor Sie Ereignisse auslösen. Wenn Onload nicht unterstützt wird, sollte davon ausgegangen werden, dass die Funktionalität nicht verfügbar ist.

1

HTML

<img id="myimage" src="http://farm4.static.flickr.com/3106/2819995451_23db3f25fe_t.jpg"/>​ 

SCRIPT

setTimeout(function(){ 
    $('#myimage').attr('src','http://cdn.redmondpie.com/wp-content/uploads/2011/05/canarylogo.png').load(function(){ 
     alert('Main Image Loaded'); 

     $('#myimage').attr('src','image.jpg').bind({ 
      load: function(){ 
       alert('Image loaded.'); 
      }, 
      error: function(){ 
       alert('Image not loaded.'); 
      } 
     }); 
    }); 
},1000); 

JS Fiddle

http://jsfiddle.net/gerst20051/sLge3/

0

Verwenden Sie eine Daten-URI ist der Weg zu gehen. Die Verwendung eines SVG anstelle eines GIF bietet jedoch mehr Flexibilität. Sie können die Größe schnell ändern. laufen diese nur in einer JavaScript-Konsole:

var width = 1; 
var height = 1; 
'data:image/svg+xml;base64,' + 
btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"/>`); 

Beispiel Ausgabe:

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxIiBoZWlnaHQ9IjEiLz4= 

warf ich zusammen a quick CodePen utility to create transparent SVGs with arbitrary dimensions. Es ist ziemlich einfach, Sie müssen es also ändern, wenn Sie dem Bild Farbe oder andere Funktionen hinzufügen möchten.

Der größte Vorteil gegenüber einem Einzelbild besteht darin, dass das Seitenverhältnis beibehalten werden kann. Dies ist wichtig für dynamisch große Bilder, da das Layout oft ausgeführt wird, bevor sich die src in ein reales Bild ändert (wenn dies der beabsichtigte Zweck ist). Bis sich das src ändert, wird das Bild quadratisch sein, was unerwünscht sein kann.

Verwandte Themen