new Image
Es macht keinen Unterschied, ob das Bild mit createElement oder mit new Image angelegt wird. Allenfalls könnte man ins Feld räumen, dass createElement konsistenter ist.
Bilder können in Javascript als mit
const myImg = document.createElement('img');
oder mit
const myImg = new Image();
angelegt werden.
Eigenschaften: Image Properties
- alt
- Setzt das alt-Attribut oder gibt den Wert des alt-Attributs zurück
- complete
- Gibt zurück, ob der Browser das Bild vollständig geladen hat. complete ist kein Event!, sondern gibt true oder false zurück.
- crossOrigin
- Setzt die CORS-Einstellung (Cross Origin) oder gibt sie zurück
- height
- Setzt die Höhe des Bildes oder gibt des Wert des height-Attributs zurück
- isMap
- Setzt ein Bild als Teil einer serverseitigen Image Map oder gibt zurück, ob das Bild Teil einer server-seitigen Image Map ist
- naturalHeight
- Gibt die (physikalische) Höhe des Bildes zurück
- naturalWidth
- Gibt die (physikalische) Breite des Bildes zurück. Das Bild muss vollständig geladen sein, bevor die Größe des Originals mit Javascript naturalHeight und naturalWidth bestimmt werden kann (ab IE9).
- src
- Setzt das src-Attribut des Bildes oder gibt des Wert des src-Attributs zurück
- useMap
- Setzt das useMap-Attribut des Bildes oder gibt den Wert des useMap-Attributs zurück
- width
- Setzt die Breite des Bildes oder gibt des Wert des width-Attributs zurück
- align, border, hspace, longDesc, name, vspace
- veraltet und nicht mehr in HTML5 vertreten
Javascript fetch HEAD kann schon vor dem Laden des Bildes die Dateigröße auslesen, während die Abmessungen des Bildes erst nach dem Laden abgefragt werden können.
Javascript Abfrage: Bild geladen?
Bilder werden geladen, nachdem ein HTTP-Request für das Bild abgesendet wurde. Das passiert entweder durch ein img-Tag oder durch einen Funktionsaufruf.
Beim window onload Event sind das »DOM, CSS-Dateien und Bilder geladen«. Das DOMContentLoaded Event hingegen feuert bereits, wenn das HTML DOM vollständig geladen und navigierbar ist – ohne auf das Laden von CSS-Dateien, Bilder und iframes zu warten (ähnlich wie jQuery ready).
Genauso sieht es aus, wenn das Script im Fuß der Seite vor dem schließenden body-Tag sitzt: Dann ist das Dokument geladen, aber das Bild u.U. noch nicht.
Werden Medien z.B. mit Javascript aufgrund einer Benutzeraktion geladen, entsteht der gleiche Ablauf.
button.addEventListener ('click', function () { const img = document.createElement ('img'); img.alt = `Bild mit JavaScript laden`; console.log ('1 img-Element erzeugt'); img.onload = function () { console.log ('2 Bild geladen', this.naturalHeight, this.naturalWidth ); document.querySelector('#scriptloader').append(img); }; console.log ('3 Bildquelle'); img.src='snail.webp'; });
Die Konsole zeigt die Reihenfolge der Aktionen: 1,3,2. Es ist wichtig, dass zuerst der Handler image.onload oder image.addEventListener("load", function () {}) aufgerufen wird, und erst danach image.src. Wenn das Bild bereits im Cache liegt, würde anderenfalls das Event verpasst.
Der Browser wartet nicht ab, bis das Bild fertig geladen ist, sondern führt Anweisungen, die auf image.onload und image.src folgen, sofort weiter aus. Der Browser triggert das onload-Event und benachrichtig das Script etwas später, dass das Bild geladen ist – erst dann werden die Anweisungen innerhalb von image.onload ausgeführt.
Wenn es wichtig ist, dass Anweisungen in einer bestimmten Reihenfolge ausgeführt werden, kann eine callback-Funktion eingreifen.
Spinner zeigen, bis ein Bild geladen ist
Da bei sehr großen Bildern eine Weile ins Land gehen kann, bis der Browser das Bild vollständig geladen hat, zeigen Galerien und Slideshows einen Spinner.
Der HTML-Teil ist einfach
<div id="buffalo">
<img id="thumbnail" src="buffalo-mini.webp" width="250" height="145" … >
</div>
Das Skript erzeugt beim Klick auf den Thumbnail ein Element für den Overlay, ein Element für den Spinner und das img-Element für den Spinner (animiertes SVG).
document.getElementById('thumbnail').addEventListener('click', () => { const overlay = document.createElement ("div"); overlay.id = "overlay"; document.querySelector ("#buffalo").append (overlay); const spinner = document.createElement ("div"); spinner.classList.add ("spinner"); document.querySelector ("#buffalo").append (spinner); const img = document.createElement ("img"); img.src = "spinner.svg"; spinner.append (img); spinner.style = "display: block"; });
Die große Version des Bildes wird erst mit dem Klick erzeugt. Bis das Bild im Browser geladen ist, dreht sich der Spinner. setTimeout () ist nur für Testzwecke eingebaut und simuliert die Ladezeit des Bildes, denn nach dem ersten Versuch liegt die große Bildversion im Cache und der Spinner wird kaum Zeit haben, seine Runden zu drehen.
Die restlichen Anweisungen gehen auf [1].
const highRes = new Image; highRes.addEventListener ('load', () => { setTimeout ( () => { overlay.append(highRes); }, 2000); }); highRes.src = "buffalo-mini-2500.webp"; highRes.onclick = function () { overlay.remove(); spinner.remove (); }
highRes.src = "…" darf erst nach dem eventListener für das load-Event aufgerufen werden, denn die Anweisung wird sofort ausgeführt, während der asynchrone eventListener nach im Wartezustand ist.
Am Ende entfernt ein Klick auf den Overlay sowohl den Overlay als auch den Spinner.
Nach dem Testen die beiden Zeilen für den Timeout löschen – nicht vergessen!
Das CSS trägt einen großen Teil der Verantwortung:
#buffalo {
position: relative;
}
#overlay {
position: absolute;
left: 0;
max-width:100%;
z-index: 10;
}
.spinner {
position: absolute;
display: none;
}
Image Preload mit Javascript
Wenn ein Image Objekt erzeugt wurde und dem Objekt eine URL zugewiesen wird, lädt der Browser das Bild in seinen Cache, z.B. um das Bild später bei einem Klick auf einen Button oder nach längerem Scrollen ohne Verzögerung anzuzeigen.
<script> let myImage = new Image(); myImage.src = 'einbild.jpg'; </script>
An dieser Stelle hat der Browser das Bild in den Cache geladen und das Image-Objekt myImage enthält das Bild einbild.jpg.
Heute kann allerdings ein Link mit rel="preload" im Head der Seite Ressourcen (Bilder, CSS, Scripte) elegant nach dem Laden der Seite im Voraus laden, z.B. um sie erst später auf der Seite zu zeigen oder auszuführen.
<link rel="preload" as="image" href="largemap.png" media="(max-width: 600px)">
Alternativ sorgt das HTML-Attribut loading="lazy" dafür, dass Bilder erst geladen werden, wenn der Benutzer bis in die Nähe des Bildes scrollt.
naturalWidth / naturalHeight: Größe eines Bildes
Für Slideshows und die allgegenwärtigen Lightboxen ist es oft erforderlich, die tatsächliche Größe eines Bildes herauszufinden.
Bilder werden als Thumbnail oder Vorschaubild kleiner in Webseiten gesetzt (z.B. damit sie in das Layout der Seite passen). Erst für die Darstellung in der Lightbox wird ihre »natürliche Größe« gebraucht.
<img id="theImage" src="image.png" alt="image size" width="400" height="240"> const theImage = document.getElementById("theImage"); let width = theImage.width; let height = theImage.height;
theImage.width und theImage.height liefern nur die aktuelle Größe.
let natWidth = theImage.naturalWidth; let natHeight = theImage.naturalHeight;
naturalWidth und naturalHeight liefern die physikalischen Abmessungen – die Größe des Bildes in Pixel – in allen gängigen Browsern.
let theImage = document.getElementById("theImage"); let natWidth; let natHeight; if (theImage) { if (typeof theImage.naturalWidth == "undefined") { let i = new Image(); i.src = theImage.src; natWidth = i.width; natHeight = i.height; } else { natWidth = theImage.naturalWidth; natHeight = theImage.naturalHeight; } theImage.classList.toggle('moveup'); document.getElementById('imgNaturalSize').innerHTML = "Breite " + natWidth + "px Höhe " + natHeight + 'px'; } else { theImage.classList.toggle('moveup'); document.getElementById('imgNaturalSize').innerHTML = "Bild noch nicht geladen"; }