Bilder zeitlich kontrolliert laden
Wis
- javascript
Hallo,
für die Website eines Fotografen, möchte ich gerne kontrollieren, wann welche Bilder geladen werden.
Die Seite besteht aus einem großen Bild und 16 kleinen, die per mouseover das grosse Bild verändern. Über eine preload-Funktion möchte ich die mouseover-Bilder laden, sobald die Seite aufgebaut ist. Ungefähr so:
-> lade das grosse Bild
-> zeige einen Ladebalken für das Laden der kleinen Bilder
-> lade die 16 kleinen Bilder
-> wenn die kleinen Bilder geladen sind, lade die 16 grossen Bilder (preload)
Das ganze versuche ich über eine while-Schleife zu realisieren, die solange wartet, bis das letzte kleine Bildelement geladen ist (habe keine andere Möglichkeit gefunden).
Mein Problem ist jetzt, dass der Browser den Container für die kleinen Bilder anzeigt, den Ladebalken versteckt und dann noch recht lange braucht, um die kleinen Bilder aufzubauen. So als würde die while-Schleife enden, obwohl noch nicht alle Bilder geladen sind. (Das passiert auch, wenn ich den Schutz gegen eine Endlosschleife ( && zaehler <= 50000000) rausnehme.
Habe erst vor 2 Monaten angefangen, mich mit HTML und Javascript zu befassen. Wenn also jemand eine Idee dazu hat oder einen Link bzw. Schlagwörter zu einer anderen Lösung, würde ich mich sehr freuen.
Schöne Grüße,
Wis
Hier noch die Idee als Code:
<script type="text/javascript" language="JavaScript"><!--
var ImageList = new Array();
ImageList[0] = "Bilder/IMG_001.jpg";
ImageList[1] = "Bilder/...
...ImageList[16] = "Bilder/IMG_016.jpg";
var Bilder = new Array();
function vorladen()
{for (i = 0; i < ImageList.length; i++){
var Bild = new Image();
Bild.src = ImageList[i];
Bilder[i] = Bild;
}
};
// --></script>
im body:
<div id="bild_gross">
<img id="IMG_gross" src="Bilder/IMG_001.jpg" alt="Bild" name="IMG_gross"></div>
<div id="loader">
<img id="loadergif" src="Bilder/loader.gif" name="loadergif"></div>
<div id="frame">
<a onmouseover="document.IMG_gross.src=Bilder[0].src"><img src="Bilder/klein/IMG_001_klein.jpg" alt="Bild" title="" style="float:left; margin:5px"></a>
<a onmouseover="document.IMG_gross.src=Bilder[1].src"><img src="Bilder/klein/IMG_002_klein.jpg" alt="Bild" title="" ...
... <a onmouseover="document.IMG_gross.src=Bilder[15].src"><img src="Bilder/klein/IMG_016_klein.jpg" alt="Bild" title="" style="margin:5px"></a>
</div>
und am Ende noch der Aufruf der Funktion:
<script type="text/javascript"><!--
document.getElementById("frame").style.visibility='hidden';
document.getElementById("loader").style.visibility='visible';
var zaehler = 1;
while (!(document.images[17].complete) && zaehler <= 50000000)
{zaehler++;
}
document.getElementById("loader").style.visibility='hidden';
document.getElementById("frame").style.visibility='visible';
vorladen();
// --></script>
Hi,
<script type="text/javascript" language="JavaScript"><!--
var ImageList = new Array();
ImageList[0] = "Bilder/IMG_001.jpg";
ImageList[1] = "Bilder/...
...ImageList[16] = "Bilder/IMG_016.jpg";
var Bilder = new Array();
function vorladen()
{for (i = 0; i < ImageList.length; i++){
var Bild = new Image();
Bild.src = ImageList[i];
Bilder[i] = Bild;
}
};
// --></script>
Das language-Attribut ist unsinnig.
Sobald du Bild.src einen Wert zuweist wird die Resource _asynchron_ angefordert.
Das heißt der wartet nicht bis die fertig geladen ist und macht dann erst weiter, sondern er macht weiter und lädt im Hintergrund das Bild.
Wenn du wissen willst wann das Bild fertig geladen ist müsstest du vorm zuweisen der URL an Bild.src einen Eventhandler hinzufügen der auf load wartet:
Bild.addEventListener('load',function(){});
In dessen Callback-Function weist du dann dass das Bild geladen wurde und kannst entsprechend deinen Ladebalken weiterschieben o.ä.
~dave
Hallo Dave,
vielen Dank für die schnelle Antwort. Ich habe den EventHandler anstatt der while-Schleife vorm </body>-Tag eingebaut. Es klappt auch wunderbar, wenn ich als Objekt das große Bild angebe:
document.images.IMG_001.addEventListener('load',vorladen,false);
wenn ich aber die Funktion erst nach dem Laden des letzten kleinen Bildes aufrufen möchte und es mit z.B.
document.images[15].addEventListener('load',vorladen,false);
versuche, klappt es nicht.
Gibt es da ein Problem, wenn ich auf ein Bild-Element zugreifen möchte, welches in
<a onmouseover="document.IMG_gross.src=Bilder[15].src"><img src="Bilder/klein/IMG_016_klein.jpg" alt="Bild"</a>
definiert wird? Habe es auch mit
...<img id="_016" src="Bilder/klein/IMG_016_klein.jpg" alt="Bild" name="_016"</a>
und
document._016.addEventListener('load',vorladen,false);
und ähnlichem probiert. Hängt das mit dem mouseover zusammen?
Vielen Dank,
Wis
Hi,
ich bin mir nicht ganz sicher ob ich dich richtig verstehe.
Wenn du einen load-Handler an ein bereits eingebundenes Bild anhängst kann es möglich sein dass dieses bereits geladen wurde.
Das müsstest du dann ggf. zuvor prüfen, dazu sollte sich eigentlich .complete eignen. Tut es aber nicht, da unterschiedliche Browser das unterschiedlich implementiert haben.
Was allerdings funktioniert ist zu prüfen ob .width oder .height des Bildes >0 sind.
~dave
Hi Dave,
spiele jetzt gerade mit der document.images[x].height Abfrage herum.
Aber so richtig klappt auch das nicht.
Ich habe ich mich bestimmt schlecht ausgedrückt, versuche es deswegen nochmal:
Ich habe einen Container im CSS definiert, in den ich 16 Bilder lade (jedes 75px x 75)
So:
<div id="frame_kleinebilder">
<a onmouseover="document.bild_gross.src=bild01_gross"><img src="bild01_klein.jpg" style="float:left; margin:5px"></a>
<a onmouseover="document.bild_gross.src=bild02_gross"><img src="bild02_klein.jpg" style="float:left; margin:5px"></a>
// usw bis Bild 16:
<a onmouseover="document.bild_gross.src=bild16_klein"><img src="bild16_klein.jpg" style="margin:5px"></a>
</div>
Beim mouseover über ein kleines Bild, soll dem Container mit dem großen Bild (bild.gross) das dazugehörige große Bild zugewiesen werden. Die großen Bilder sind 500px x 500px groß.
Damit das sofort eintritt, lade ich die großen Bilder mit einer preload-Funktion vor.
Weil ich aber möchte, das erst die Seite mit den kleinen Bildern komplett aufgebaut wird, möchte ich die prelaod-Funktion erst starten, wenn alles andere fertig ist.
Mein Problem ist jetzt, dass sämtliche Anfragen für die Bilder sofort gestellt werden (auch die großen Bilder für´s mouseover) und somit der Seitenaufbau sehr lange dauert.
Ich hoffe, das ist etwas verständlicher.
Ich werde die Seite mal hochladen und verlinken, dann wird es vielleicht klarer.
Erstmal vielen Dank für die Anregungen,
schöne Grüße,
Wis
Hi,
d.h. du musst erst warten bis alle kleinen Bilder geladen sind.
Wie du rausfindest wann eine beliebige Menge von Bildern fertig geladen wurde habe ich bereits geschrieben:
Wenn .width > 0 dann wurde es geladen, sonst einen Event-Handler für das load-Event. Wenn der aufgerufen wurde, ist das Bild geladen.
Nachdem alle geladen wurden möchtest du beginnen die großen Bilder zu laden.
Wie das geht hast du bereits selbst im ersten Post geschrieben.
Mir ist nicht klar wo du noch ein Problem hast.
Auch wenn ich dich am Anfang scheinbar falsch verstanden hatte solltest du doch alle nötigen Mittel kennen?
~dave
Hi Dave,
entschuldige, dass ich mich erst jetzt melde. Ich war die letzte
Woche unterwegs.
Mein Problem ist wohl in erster Linie die nicht vohandene Erfahrung.
Als ich die Seite jetzt endlich mal hochgeladen habe, funktioniert
der Eventhandler. Lokal auf meine Festplatte, wollte er nicht auf
die entscheidenen Bilder ansprechen, bin fast wahnsinnig geworden ;)
Um das ganze zu testen, gehe ich mit meinem Laptop so weit wie es geht vom Router weg,
so dass das Laden der Bilder lange dauert. Vielleicht verstehe ich auch was grundsätzlich
noch nicht: Denn wenn die Funktion vorladen() über den Eventhandler aufgerufen
wird, wird das loader.gif auf hidden gesetzt und der Container für die kleinen
Bilder auf visible. Trotzdem sind diese Bilder dann nicht sofort da,
sondern bauen sich noch langsam auf.
Hier mal die Seite.
Nochmal vielen Dank für Deine Hilfe.
LG,
Wis