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 = '...';
quelle
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!Antworten:
Da niemand hat noch keine Angaben darüber , wie gefunden hat dies angeblich verhalten, werden wir mit werden müssen zufrieden , wie es tut verhalten. Es folgen die Ergebnisse meiner Tests.
Zusammenfassend:
onload
Ereignis warten .onload
Handler nach dem Festlegen von nicht festlegensrc
und erwarten, dass er aufgerufen wird.Wenn jemand Spezifikationen findet, die dies diskutieren, werde ich stattdessen gerne ihre Antwort akzeptieren.
quelle
window.load
Ereignis. Wurden Ihre Tests nach dem Laden oder vorher durchgeführt? Erinnerst du dich?Nach der
true
Rückgabe der Kontrolle an die Rendering-Engine des Browsers werden die Testberichte in FF 4b9 und Chromium 8.0.552.237 erstellt. Ich habe diese Teile modifiziert:img.onload = function(){ // put this above img.src = … document.getElementById('onload').innerHTML = 'yes'; }; img.src = img_src; … window.setTimeout(function () { // put this inside setTimeout document.getElementById('wh').innerHTML = (img.height==img.width) && (img.height==128); }, 0);
Update: Ja, ich verstehe, dass diese 'Antwort' eher wie ein Kommentar ist, wollte aber nur darauf hinweisen. Und nach dem Testen erhalte ich reproduzierbare Ergebnisse:
setTimeout
, in beiden Browsern bekomme ichfalse
das erste Mal die Seite zu öffnen undtrue
erst nach dem Schlagen F5. Nachdem der Cache explizit geleert wurde, sagen beidefalse
nach dem erneuten Laden erneut.setTimeout
dem Breiten- / Höhentest immer zu bewertentrue
.In beiden Fällen wird das Bild erst beim erneuten Laden der Seite beim ersten Mal angezeigt.
quelle
onload
vorsrc
und nur das Verweisen auf das Bild im Rückruf funktioniert. Meine Frage ist, ob es Spezifikationen gibt, die beschreiben, wie dies funktionieren sollte.