Bildverzeichnis (Thumbnail) mit Javascript erzeugen
- javascript
Moin,
ich habe HTML-Seiten (nicht PHP) mit Bildern <img src=...> und möchte ein Bildverzeichnis dieser Seite erstellen, also die Bilder im Kleinformat zeigen. Das ist zunächst leer:
<div id="thumbnails">
</div>
für jedes Bild soll so ein Eintrag eingefügt werden:
<div>
<img src="[Dateiname]">
</div>
In Javascript mache ich dieses:
// Bildverzeichnis erstellen
var bilder = document.querySelectorAll( "img" );
console.log( bilder.length +" Bilder" );
thumbverzeichnis = "";
for ( let i=0; i<bilder.length; i++ ) {
console.log( bilder[i] );
thumbverzeichnis += "<div class='li bo'>\n";
thumbverzeichnis += bilder[i] +"\n";
thumbverzeichnis += "</div>\n";
}
document.querySelector( "#thumbnails" ).innerHTML = thumbverzeichnis;
Die Anzahl der Bilder wird korrekt gezeigt, mit console.log auch korrekt alle img-tags <img ...>
Aber nach Einfügen in #thumbnails wird nicht das Bild gezeigt, sondern sowas

Wie kann ich den String bekommen, den console.log anzeigt?
Gruß, Linuchs
Hallo Linuchs,
Moin,
ich habe HTML-Seiten (nicht PHP) mit Bildern
<img src=...>und möchte ein Bildverzeichnis dieser Seite erstellen, also die Bilder im Kleinformat zeigen.
Bei reinen HTML-Seiten würde ich nicht bei jedem Neuladen mit JavaScript Bitmap-Miniaturansichten generieren. Ich würde dabei zwei Fälle unterscheiden:
Dann verwende einfach die vorhandenen Bilder und skaliere diese mit CSS:
<div class="bildverzeichnis">
<a href="#bild1"><img src="bilder/haus.jpg" alt="Haus"></a>
<a href="#bild2"><img src="bilder/garten.jpg" alt="Garten"></a>
<a href="#bild3"><img src="bilder/zaun.jpg" alt="Zaun"></a>
</div>
.bildverzeichnis {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
gap: 1rem;
}
.bildverzeichnis img {
display: block;
width: 100%;
height: 8rem;
object-fit: contain;
}
Dann würde ich das 1x
a. manuell beim Upload
b. mit PHP machen.
Bis bald!
Jonathan
Hallo Jonathan,
danke für die Antwort. So wie du es vorschlägst, habe ich es bisher.
Aber wenn ich dann ein Bild irgendwo in den Text einfüge, muss ich diesen Eintrag bei den Thumbnails nochmals machen. Das soll Javascript erledigen, kann doch eigentlich nicht schwer sein.
Gruß, Linuchs
Hallo Linuchs,
in bilder[i] ist kein html, sondern das Image-Objekt. Und bei der Verkettung mit einem String wird daraus eben [object HTMLImageElement].
Du müsstest die outerHTML Eigenschaft kopieren. Dann kommt auch das obligatorische alt-Attribut mit.
Aber ideal ist das alles nicht. Ich habe nur keine Zeit für Details.
Rolf
@@Rolf B
Du müsstest die outerHTML Eigenschaft kopieren.
Ja, damit ist das schnell gemacht: Warschau 1
Dann kommt auch das obligatorische alt-Attribut mit.
Hm, und wenn da kein Alternativtext ist? Dann könnte man sich den aus der Bildunterschrift rausholen. Dann muss man sich das img-Element zusammenbasteln: Warschau 2
Es sei denn, es ist eine Verknüpfung vom Bild zur Bildunterschrift mit aria-describedby (oder aria-labelledby) vorhanden; die geht dann bei outerHTML auch mit zum Thumbnail: Warschau 3
🖖 Live long and prosper
@@Linuchs
var bilder = document.querySelectorAll( "img" );
Nö, das ist Quatsch. document.images existiert bereits.
for ( let i=0; i<bilder.length; i++ ) {
Die Tage der guten alten FOR-Schleife sind aber nun auch schon eine ganze Weile gezählt. Es gibt sicher noch Anwendungsfälle dafür, aber alle Elemente einer Sammlung zu durchlaufen, zählt nicht dazu; dafür gibt es for … of.
Dann musst du nicht mit Indizes rummachen und der Code wird lesbarer:
for (const image of document.images) {
console.log(image);
}
Für etliche Objekttypen gibt es auch die forEach-Methode; nicht aber für HTMLCollection, was document.images ist. Kann man aber fix in ein Array umwandeln:
[...document.images].forEach(image => {
console.log(image);
});
thumbverzeichnis += "<div class='li bo'>\n";
Das ist unlesbarer Code. Wofür steht 'li'? Wofür steht 'bo'?
Und wozu sollen die div-Container überhaupt gut sein? Nur die img-Elemente sollten doch reichen?
Und die Zeilenumbrüche interessieren den HTML-Parser nicht die Bohne, die \n können weg.
🖖 Live long and prosper
Hallo Gunnar Bittersmann,
Kann man aber fix in ein Array umwandeln
Bevor ich DAS täte, täte ich aber lieber querySelectorAll verwenden. Und zwar nicht auf das Dokument, sondern mit einem Selektor, der nur die Ausgangsliste trifft.
Grund 1: es könnte noch anderswo auf der Seite Bilder geben
Grund 2: images ist eine Live-Collection. Mit [... images] wird eine statische Kopie daraus, und das ist viel wichtiger, als for...of einsetzen zu können. Falls du die Thumbs hinter den Originalbildern erzeugst, dürfte ohne Kopie eine Endlosschleife drohen. Und wenn Du sie vorher einfügst, stimmen ohne Kopie die Indexe nicht mehr.
Die Kopie ist aber unnötiger Aufwand, denn querySelectorAll ist zielgenauer und liefert von vornherein eine statische NodeList.
Rolf
Hallo Gunnar,
Das ist unlesbarer Code. Wofür steht 'li'? Wofür steht 'bo'?
.li {float:left}
.bo {border...}
Es ist also eine bestimmte Art von Bildern, die im Text zu sehen sind.
Ich weiß, für die Frage ist das überflüssig. Aber wenn ich den Code für die Frage verändere, schleichen sich mit Sicherheit Fehler ein.
Gruß, Linuchs
Danke für eure Nachfragen und Anregungen.
Der Klartext bei console.log auf Objekte hat mich gedanklich in eine Sackgasse geführt, der ist programmtechnisch nicht (so einfach) zu haben.
Ich brauche vom img-Objekt den src Wert und - danke für die Anregung - den alt Wert, und schon funktioniert es prächtig:
// Bildverzeichnis erstellen
var bilder = document.querySelectorAll( ".bo img" );
var thumbverzeichnis = "";
for ( let i=0; i<bilder.length; i++ ) {
let src = bilder[i].src;
let alt = bilder[i].alt
console.log( src +"|" +alt );
thumbverzeichnis += "<div class='li bo'>";
thumbverzeichnis += "<img src='" +src +"' alt='" +alt +"'>";
thumbverzeichnis += (i+1) +". " +alt;
thumbverzeichnis += "</div>";
}
document.querySelector( "#thumbnails" ).innerHTML = thumbverzeichnis;
Gruß, Linuchs
Hallo Linuchs,
naja, für einen gewissen Wert von "funktioniert".
Deine bo li Namenswahl hat Gunnar schon angemerkt. Dass Du mit float hantierst statt eine Flexbox mit flex-flow:row wrap zu verwenden, finde ich auch nicht gerade modern. Die Thumbs sollten eine Liste sein, keine div-Wüste. Und wenn Du Thumb-Unterschriften setzen möchtest, dann mach daraus eine figure mit figcaption.
Aber wenn Du zufrieden bist und es nur für Dich ist, will ich nichts weiter sagen…
Rolf
@@Rolf B
naja, für einen gewissen Wert von "funktioniert".
Der näher an 0 als an 1 liegt?
Und wenn Du Thumb-Unterschriften setzen möchtest, dann mach daraus eine figure mit figcaption.
Hm … “The figure element represents some flow content, optionally with a caption, that is self-contained (like a complete sentence) and is typically referenced as a single unit from the main flow of the document”, sagt die Spec.
Letzteres “is typically referenced as a single unit from the main flow of the document” sehe ich hier nicht gegeben. Nicht alles, was Bild mit Bildunterschrift ist, ist figure.
🖖 Live long and prosper
@@Linuchs
Ich brauche vom img-Objekt den src Wert und - danke für die Anregung - den alt Wert, und schon funktioniert es prächtig:
Zu der Einschätzung kannst du nur gelangt sein, weil du nicht getestet hast. Aber man sieht den Fehler auch schon im Code.
Übrigens wäre es schön, wenn du bei Codeblöcken immer die Sprache (hier: JavaScript) angibst, dann gibt’s auch Syntax-Highlighting. Ich hab das mal für dich gemacht.
var bilder = document.querySelectorAll( ".bo img" ); var thumbverzeichnis = "";
var? Das sollte anno 2026 nicht mehr auftauchen.
bilder verändert sich nicht mehr, thumbverzeichnis hingegen doch. Also:
const bilder = document.querySelectorAll( ".bo img" );
let thumbverzeichnis = "";
for ( let i=0; i<bilder.length; i++ ) {
Immer noch? Warum?
thumbverzeichnis += "<div class='li bo'>"; thumbverzeichnis += "<img src='" +src +"' alt='" +alt +"'>"; thumbverzeichnis += (i+1) +". " +alt; thumbverzeichnis += "</div>";
Das ist unlesbarer Code. So wird’s lesbar:
thumbverzeichnis += `<div class='li bo'>
<img src='${src}' alt='${alt}'>
${i+1}. ${alt}
</div>`;
Und jetzt ist auch der Fehler deutlich zu sehen: alt wird zweimal ausgegeben, von Screenreadern also zweimal vorgelesen. Das will man nicht, es ist hier alt='' zu setzen, so wie es auch in meinen bereits verlinkten Beispielen der Fall ist. Die hattest du dir angesehen?
thumbverzeichnis += `<div class='li bo'>
<img src='${src}' alt=''>
${i+1}. ${alt}
</div>`;
Du willst die Bilder durchnummerieren? Das deutet darauf hin, dass du ol/li verwenden willst anstatt div.
🖖 Live long and prosper
@@Gunnar Bittersmann
for ( let i=0; i<bilder.length; i++ ) {Immer noch? Warum?
Falls die Antwort darauf „Nummerierung“ sein sollte – die bekommt man auch anders hin.
forEach kann man auch mit zusätzlichem Parameter aufrufen:
….forEach((item, index) => { … });, dann hat man innerhalb der Funktion Zugriff auf den aktuellen Index.
Die Nummerierung kann man aber auch CSS überlassen: siehe counter().
Und wenn man wie bereits vorgeschlagen Listen-Markup verwendet, kann man sich das Initialisieren und Hochsetzen eines eigenen Zählers sparen und den bei Listen schon vorhandenen Zähler list-item verwenden. Beispiel
🖖 Live long and prosper