Rolf B: JavaScript Slideshow

Beitrag lesen

Hallo User123,

das ist aber extremes setTimeout Gewusel, das Du da veranstaltest. Sehe ich das richtig, dass Du nur 2 Fotos abwechelnd anzeigst? Was soll das erst bei 30 Fotos werden?!

Ich glaube auch, dass es wenig sinnvoll ist, einen ready-Handler in einem setInterval-Callback zu verwenden.

Man erkennt, dass Du gerade erst einsteigst. Beschäftige Dich mit den Konzepten „Variablen“ und „Bedingte Anweisungen“. Ohne die lassen sich kaum sinnvolle Programme erstellen.

Übrigens ist es in jQuery seit Version 3.0 Standard, einen Ready-Handler per $(...) zu registrieren und nicht per $(document).ready(...). Da es diese Möglichkeit schon seit jQuery 1.0 gibt, kann man diese Vorgehensweise generell empfehlen.

Wie auch immer - du hast richtig erkannt, dass setInterval den ersten Aufruf des Intervall-Callbacks nicht sofort durchführt, sondern erst nach Ablauf der ersten Intervallfrist. Man könnte das so lösen, dass man die Callback-Funktion für setInterval nicht direkt übergibt, sondern als eigenständige Funktion schreibt. Und dann ruft man einmal diese Funktion auf und direkt dahinter setInterval. In etwa so:

$(function() {
   zeigeBilddurchlauf();
   setInterval(zeigeBilddurchlauf, 10000);
});

function zeigeBilddurchlauf() {
   // setTimeout Gestrüpp
}

Aber das ist nicht schön, wirklich nicht. Bei 2 Bildern geht es noch, bei 20 oder 30 Bildern wird es tödlich. Deine fadeIn/fadeOut Steuerung kann man mit jQuery machen, sicher, aber es gibt in allen relevanten Browsern (Internet Explorer ab Version 10) die CSS Eigenschaften transition und opacity, womit Du das Ein-/Ausblenden auch ohne jQuery durchführen kannst. Einfach beim alten Bild die opacity auf 0 (=transparent) setzen, beim neuen Bild auf 1 (=undurchsichtig) und mit transition:opacity 1s; dafür sorgen, dass der Übergang auf eine Sekunden gestreckt wird. Damit erreichst Du auch, dass das alte Bild wegblendet, während das neue Bild schon einblendet.

Eine einfache (aber ggf. netzwerkintensive) Version einer Slideshow braucht

  • einen Container mit einem img-Element pro Bild
  • alternativ ein figure-Element pro Bild, wenn Du auch eine Überschrift (figcaption) oder Zusatztexte unterbringen willst
  • eine Variable, die die aktuelle Bildnummer festhält
  • einen setInterval-Handler, der das aktuelle Bild ausblendet, die Bildnummer erhöht (bzw. bei Überlauf auf 0 zurücksetzt) und das neue Bild einblendet.
  • der setInterval Handler kann für das neue Bild, das er einblenden möchte, noch die Eigenschaft complete des Bildes abfragen. Diese Eigenschaft steht auf true, wenn das Bild geladen ist. Ist sie false, wird das Bild übersprungen und das nächste probiert. Oder man bleibt auf dem aktuellen Bild. Das richtige Vorgehen hängt auch daran, ob die Reihenfolge der angezeigten Bilder von Bedeutung ist oder nicht.
  • die Variante 2 kann man verfeinern, indem man den setInterval-Handler schneller laufen lässt als nötig (z.B. alle 0.5s). Im setInterval-Handler läuft ein Countdown. Bei einer Bildwechselzeit von 5s und einer Intervallfrequenz von 0.5s würde er bei 10 beginnen. Wenn der Countdown abgelaufen ist, wird der complete-Status des nächsten Bildes geprüft. Ist es da, wird der Countdown zurückgesetzt und das Bild aktiviert. Ist es noch nicht da, bleibt man auf dem aktuellen Bild und der Countdown tickt weiter (ins negative - was nicht stört wenn man < 1 abfragt und nicht == 0.

Die Registrierung des setInterval-Handlers kann man in einem ready-Handler machen. Es ist allerdings riskant, weil der ready-Handler anläuft, sobald das DOM fertig ist. "DOM fertig" ist was anderes als "alle Bilder geladen" und wenn Du 40 Bilder hast, dann lädt der Browser die nicht zwangsweise in der Reihenfolge, wie sie im HTML auftauchen. Da hilft dann die erwähnte Nutzung des complete-Status.

Eine komplexere Lösung verwendet nur zwei img Elemente. Eins ist aktuell und wird angezeigt, das andere ist ausgeblendet und dient zum Laden des nächsten Bildes. Wenn der Zeitpunkt zum Bildwechsel kommt, wird umgeblendet und die beiden wechseln die Rollen. Das hat den Vorteil, dass zu Beginn erstmal nur zwei Bilder geladen werden müssen. In einem langsamen Netz ist das ein deutlicher Vorteil. Auch hier kann man complete nutzen, um nicht auf ein Bild umzuschalten, das noch nicht fertig geladen ist.

Rolf

--
sumpsi - posui - obstruxi