• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[GELÖST] Bilder vorladen und Ladeanimation

J

j-l-n

Guest
Folgendes Szenario: auf einer Seite sind sehr viele Bilder eingebunden. Beim Laden gibt es nun deswegen den unschönen Effekt, dass sich diese Bild für Bild aufbauen - sieht man auch deutlich an den alt-Titeln.
Nun möchte ich, dass alle Bilder direkt beim Aufruf der Seite schon einmal in der passenden Größe als Platzhalter geladen werden und solange eine Ladeanimation im jeweiligen Bild erfolgt.
Wie könnte ich das am besten machen? Ich habe mir überlegt, alle img-Tags inklusive height und width am Anfang auszulesen und den href zu dem der Ladeanimation ändern.
Aber wie lade ich dann derweil die anderen Bilder? Muss das dann unbedingt über ein 1x1-Pixel gehen, oder würde es auch anders funktionieren?
 
Zuletzt bearbeitet von einem Moderator:
Beim auslesen die Referenz des im-Tag mit zur Bildquelle speichern und dann wie bei einem klassischen Preloader weitermachen. Und wenn das Bild geladen ist, über die gespeicherte Referenz zurück tauschen.
 
Würde so etwas in der Richtung Sinn machen?
Code:
document.addEventListener("DOMContentLoaded", function(){
  preloadImages("loading.gif");
});

function preloadImages(animation){
  "use strict";
  var cacheDiv = document.createElement("div");
  cacheDiv.style.display = "none";
  var imgs = document.getElementsByTagName("img");
  for(var i = 0; i < imgs.length; i++){
    var original_src = imgs[i].src;
    var cacheImg = document.createElement("img");
    cacheImg.src = original_src;
    cacheImg.style.display = "none";
    cacheDiv.appendChild(cacheImg);
    imgs[i].src = animation;
    imgs[i].onload = function(){
      imgs[i].src = original_src;
      this.onload =  null;
    }
  } 
}
 
Bei diesem Ansatz müssten aber alle Bilder gleich groß sein, da sonst die Ladeanimation verzerrt dargestellt würde.

Auch ist dein Code etwas seltsam. Für was das cacheDiv? Warum setzt du alles auf display: none, wenn du es sowieso nicht ins DOM einhängst?
Auch ist das .onload auf dem falschen <img> regstriert - das muss auf das cacheImg. Zusätzlich kannst du Probleme bekommen, wenn die Bilder schon im Cache sind - das bekommst du in den Griff, indem du zuerst .onload zuweist und dann erst .src

Aber warum machst du das eigentlich nicht mit CSS?
Code:
<!DOCTYPE html>

<html>
<head>
<title>Fenstertitel</title>
<style type="text/css">
img {
	background-image: url(/Bilder/wait2.png);
	background-position: 50% 50%;
	background-repeat: no-repeat;
}
</style>
</head>
<body>
<img height="200" width="300" alt="test" src="/server/delay.php?delay=10000">tja<br>jlkj
</body>
</html>
 
Für was das cacheDiv? Warum setzt du alles auf display: none, wenn du es sowieso nicht ins DOM einhängst?
Das cacheDiv benötige ich noch an anderer Stelle für etwas anderes, deswegen.
Bei der CSS-Lösung ist das Problem, dass zum einen der alt-Text trotzdem angezeigt wird, zum anderen, dass die Bilder von der Größe her nicht stimmen und sich so beim Aufbau wieder alles verschiebt.
 
Na dann schau dir mal daa Script von Github an, das ich verlinkt habe.
Ich denke, das kommt der Sache sehr nahe und du kannst es ja noch etwas deinen Wünschen anpassen.
 
Ich werd's mir auf jeden Fall anschauen. Wollte das Ganze aber eigentlich ohne jQuery realisieren. Und das mit den verschiedenen CSS-Klassen finde ich auch irgendwie umständlich...
 
Würde so etwas in der Richtung Sinn machen?
Hast du das denn mal ausprobiert?

Hatte mal so etwas Ähnliches gemacht, war ein kombinierter Thumbnail preloader für eine Seite mit vielen Bildern, langgsamen Internet usw...
Muss mal schauen ob ich den Code nochmal finde, ist schon gefühlt eine Ewigkeit her...
 
Habe das Script gefunden und mal angeschaut. Ist nicht die Welt aber seiner Zeit hatte es funktioniert.
Habe es mal auf nötigste gekürzt und IE<9-Altlasten rausgeschmissen, dafür aber noch schnell kkapsners Idee mit reingebaut.
Aufgerufen wird es so:
Code:
document.addEventListener('DOMContentLoaded', function () {
	'use strict';
	preloadImages({
		bgImage: 'images/loading.gif',
		transImage: 'images/transparent.gif',
		className: 'preloader',
		callback: function () {
			alert('All images loaded !!!');
		}
	});
});
bgImage: Falls gesetzt, wird ein CSS eingebunden, so wie kkapsners Vorschlag, mit der angegebenen Hintergrundgrafik (optional).
transImage: Das ist die Alternativgrafik während des Ladevorgangs (sollte als midest-Option angegeben werden, da sonst sinnfrei). Ein transparentes Bild wäre in Verbindung mit bgImage gut, da dann eine Skalierung entfällt.
className: Angeben falls man nur img's mit der angegebenen Klasse behandelt werden sollen (wird auch beim erzeugten CSS berücksichtigt).
callback: Eine Funktion, welche ausgeführt wird, sobald alle Bilder geladen wurden.

So und hier das Script:
Code:
function preloadImages(options) {
	'use strict';
	var	i,
		process,
		default_options = {
			bgImage: false,
			transImage: false,
			className: false,
			callback: false
		};

	options = options || {};
	if (typeof options !== 'object') {
		return;
	}

	for (i in default_options) {
		if (default_options.hasOwnProperty(i)) {
			if (options[i] === undefined) {
				options[i] = default_options[i];
			}
		}
	}

	process = {
		pictures: null,
		picturesGetter: [],
		picturesLoaded: 0,
		addCSS: function () {
			var head = document.head || document.getElementsByTagName('head')[0],
				style = document.createElement('style'),
				selector = 'img',
				css;

			if (options.className) {
				selector += '.' + options.className;
			}

			css = selector + ' {' +
				'	background-image: url(' + options.bgImage + ');' +
				'	background-position: 50% 50%;' +
				'	background-repeat: no-repeat;' +
				'}';

			style.type = 'text/css';
			if (style.styleSheet) {
				style.styleSheet.cssText = css;
			} else {
				style.appendChild(document.createTextNode(css));
			}
			head.appendChild(style);
		},
		loaded: function () {
			process.pictures[this.alt].src = this.src;
			if (process.callback) {
				process.picturesLoaded += 1;
				if (process.picturesLoaded === process.pictures.length) {
					process.callback();
				}
			}
		},
		preloader: function () {
			var i,
				i_max;

			i_max = this.pictures.length;
			for (i = 0; i < i_max; i += 1) {
				this.picturesGetter[i] = new Image();
				this.picturesGetter[i].alt = i;
				this.picturesGetter[i].onload = process.loaded;
				this.picturesGetter[i].src = this.pictures[i].src;
				if (options.transImage) {
					this.pictures[i].src = options.transImage;
				}
			}
		},
		init: function () {
			var selector = 'img';

			if (options.bgImage) {
				this.addCSS();
			}

			if (options.callback && typeof options.callback === 'function') {
				this.callback = options.callback;
			}

			if (document.querySelectorAll) {
				if (options.className) {
					selector += '.' + options.className;
				}
				this.pictures = document.querySelectorAll(selector);
				if (this.pictures.length) {
					this.preloader();
				}
			}
		}
	};

	process.init();
}

Ist wie gesagt nur mal schnell von dem alten ursprünglichen Script transformiert.
 
Hab das jetzt nur kurz testen können, aber ist total stark! Danke dir, miniA4k!
Werde mir das bei Gelegenheit noch genauer anschauen und evtl. noch etwas anpassen...
 
dass die Bilder von der Größe her nicht stimmen und sich so beim Aufbau wieder alles verschiebt.
Diesen Einwand verstehe ich nicht. Du musst doch immer im <img> die Höhe und Breite vorgeben, wenn du nicht willst, dass sich etwas verschiebt. Woher soll denn der Browser bei den anderen Ansätzen wissen, wie groß das Bild ist?
 
Diesen Einwand verstehe ich nicht. Du musst doch immer im <img> die Höhe und Breite vorgeben, wenn du nicht willst, dass sich etwas verschiebt.
War etwas missverständlich formuliert: Bei den Bildern habe ich die Größe schon angegeben. Ich meinte damit, dass zuerst die gesamten alt-Beschreibungen als Text angezeigt werden, und über diesem Text jeweils die Ladegrafik. Und während es dann lädt, bauen sich nach und nach die Bilder auf, wodurch der restliche alt-"Text" davor "hergeschoben" wird...
 
Nur so eine OT-Frage, warum benutzt du überhaupt alt ?
Könnte es überhaupt sein, das Bilder nicht angezeigt werden?

Falls du eine Beschreibung des Bildes machen willst, ist title eigentlich besser.
 
Ich würde sagen, weil das alt den alternativ-Text der darzustellenden Grafik in Kurzform wiedergibt und so lange angezeigt wird, bis die Grafik geladen ist. Oder auch angezeigt wird, falls die Grafik beschädigt oder nicht (mehr) vorhanden ist. Ein fehlendes alt-Attribut wird dir jeder gescheite Validator melden wenn dieser auch die Web Content Accessibility Guidelines (WCAG) berücksichtigt.
 
Jetzt hat miniA4k sozusagen schon das Antworten für mich übernommen... ;)
 
bauen sich nach und nach die Bilder auf, wodurch der restliche alt-"Text" davor "hergeschoben" wird...
Ach so - ja, das lässt sich mit CSS nicht verhindern.

ist title eigentlich besser.
title ist für eine Beschreibung sinnvoller - ja. Aber das für ist alt auch gar nicht gedacht. Steht ja für alternative und ist hald das, was alternativ angezeigt/vorgelesen werden soll, wenn das Bild nicht gesehen werden kann/will (wenn man z.B. auf seinem Smartphone keine Flatrate oder eine extrem langsame Verbindung hat, ist es sinnvoll keinerlei Bild laden zu lassen und dann nur per Klick die interessanten sich zu holen. Ein Bild, bei dem dann alternativ "logo" angezeigt wird, kann man sich dann sparen).
 
Ja mit dem Smartphone gebe ich dir Recht, aber ansonsten habe ich es noch nie erlebt, das in dem Sinne ein Ladevorgang zu bemerken war. Die Bilder auf Websites sind eigentlich immer direkt nach dem Aufruf vorhanden.
 
Die Bilder auf Websites sind eigentlich immer direkt nach dem Aufruf vorhanden.
...nicht wenn wie in diesem Fall 22,3 MP-Fotos in voller Auflösung geladen werden bzw. sehr viele Thumbnails eingebunden sind. Bei vielen kleinen Bildern kommt noch hinzu, dass ein Browser in der Standardeinstellung nur wenige Verbindungen gleichzeitig aufmacht, wodurch immer nur beispielsweise 5 auf einmal geladen werden können. Deswegen wird auch SPDY - The Chromium Projects entwickelt - Demo hier unter dem Punkt "Härtetest": Prüfen Sie, ob Ihr Browser SPDY unterstützt - Testseite für SPDY
Und die Anzahl paralleler Verbindungen lässt sich durch Pipelining erhöhen: Firefox: Seiten schneller laden durch Pipelining - Tipp für Mozilla-Browser | TecChannel.de
 
Zurück
Oben