Betrachten Sie den folgenden (fragilen) JavaScript-Code:
var img = new Image;
img.src = "data:image/png;base64,..."; // Assume valid data
// Danger(?) Attempting to use image immediately after setting src
console.log( img.width, img.height );
someCanvasContext.drawImage( img, 0, 0 );
// Danger(?) Setting onload after setting src
img.onload = function(){ console.log('I ran!'); };
Die Fragen)
- Sollte die Bildbreite und -höhe sofort korrekt sein?
- Sollte die Leinwandzeichnung sofort funktionieren?
- Sollte der
onload
Rückruf (eingestellt nach dem Ändern des src) aufgerufen werden?
Experimentelle Tests
Ich habe eine einfache Testseite mit ähnlichem Code erstellt. In Safari haben meine ersten Tests, sowohl beim lokalen Öffnen der HTML-Seite ( file:///
URL) als auch beim Laden von meinem Server, gezeigt, dass alles funktioniert: Die Höhe und Breite sind korrekt, das Zeichnen der Leinwand funktioniert und das wird onload
auch ausgelöst.
In Firefox v3.6 (OS X) zeigt das Laden der Seite nach dem Starten des Browsers, dass die Höhe / Breite unmittelbar nach dem Einstellen nicht korrekt ist drawImage()
. (Der onload
Handler wird jedoch ausgelöst.) Beim erneuten Laden der Seite wird jedoch angezeigt, dass die Breite / Höhe unmittelbar nach dem Einstellen und drawImage()
Arbeiten korrekt ist . Es scheint, dass Firefox den Inhalt der Daten-URL als Bild zwischenspeichert und sofort verfügbar hat, wenn er in derselben Sitzung verwendet wird.
In Chrome v8 (OS X) werden dieselben Ergebnisse wie in Firefox angezeigt: Das Image ist nicht sofort verfügbar, es dauert jedoch einige Zeit, bis es asynchron von der Daten-URL "geladen" wird.
Zusätzlich zum experimentellen Beweis, welche Browser die oben genannten Funktionen ausführen oder nicht, würde ich gerne Links zu Spezifikationen verwenden, wie sich dies verhalten soll. Bisher war mein Google-Fu der Aufgabe nicht gewachsen.
Auf Nummer sicher gehen
Wenn Sie nicht verstehen, warum das oben Genannte gefährlich sein kann, sollten Sie aus Sicherheitsgründen solche Bilder verwenden:
// First create/find the image
var img = new Image;
// Then, set the onload handler
img.onload = function(){
// Use the for-sure-loaded img here
};
// THEN, set the src
img.src = '...';
onload
bevor Sie das einstellensrc
. Wenn das Ladeereignis jedoch manchmal in der aktuellen Konstellation ausgelöst wird, ist das Festlegen des URI "Daten" tatsächlich asynchron - was mich überraschen würde. Interessant!