Sehr einfache Slideshow mit Javascript und CSS

Slideshows sind für viele Webseiten ein unverzichtbarer Teil des Layouts. Es gibt sie in unzähligen Variationen zum freien Download, aber fast immer bringen sie aufwändige CSS-Dateien und ebenso aufwändige Scripte mit.

Javascript Slideshow, no jquery, but CSS

Slideshow mit Javascript und CSS transition

Die Slideshow ist einfach, aber bietet Variationen oder Optionen: Slide in from top, from bottom, from left oder fadeIn/Out. Vanilla Javascript ist der Ausdruck für einfaches JavaScript ohne Libraries oder dem Overhead von jQuery. Dank CSS3 und Javascript-Methoden wie querySelector und querySelectorAll sitzen Effekte mit wenigen Anweisungen.

Do it yourselft-Slideshow mit purem Javascript:

pano-rheindeich-920x263
Panorama Rheindeich
Rinder auf dem Rheindeich bei Orsoy
Kirche in den Bergen
Kirche in den Bergen
Panorama Ostsee
Taucherglocke Grömitz

HTML und CSS für die Slideshow

Ohne Javascript sind die Bilder durch display:none ausgeschaltet. Damit ein Browser bei deaktiviertem Javascript etwas anzuzeigen hat, sollte noch ein Hintergrundbild eingesetzt werden.

<div id="slideshow">
  <div class="slides">
  	<figure>
  		<img src="pano-1.webp" … >
  		<figcaption>Alte Rheinarme in Vluyn</figcaption>
  	</figure>
	<figure>
		<img src="pano-2.webp" …>
		<figcaption>Die Taucherglocke von Grömitz</figcaption>
	</figure>
	<figure>…</figure>
  </div>
	<button class="prev">prev</button>
	<button class="next">next</button>
  </div>
</div>

Das Script selektiert die Elemente anhand der Klasse slides. Es müssen also keine Bilder sein, die in der Slideshow gezeigt werden, sondern die Slideshow kann auch für andere Elemente eingesetzt werden.

#slideshow {
	position: relative;
	width: 100%;
	height: 280px;
	overflow: hidden;
  
	.slides figure {
		position: absolute;
		margin:0;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		opacity: 0;
		z-index: 0;
		transition: opacity 1s ease, transform 1s ease;
		
		figure.active {
			opacity: 1;
			z-index: 1;
		}

		img { object-fit: cover; }
		
		figcaption {
			position: absolute;
			bottom: 0;
			z-index: 1000;
			background: hsla(0,0%,100%,0.3);
			padding: 0.5rem;
			width: 100%;
		}
	}
	
	button {
		position: absolute;
		top: 50%;
		transform: translateY(-50%);
		font-size: 2rem;
		background: rgba(0, 0, 0, 0.4);
		color: white;
		border: none;
		cursor: pointer;
		padding: 0.2em 0.5em;
		z-index: 2;
	}
	
	.prev { left: 10px; }
	.next { right: 10px; }
}

Das Element mit der Klasse slideshow ist relativ positioniert, damit die Bilder absolut innerhalb der Slideshow liegen.

Das ist schon das komplette CSS für eine Slideshow, die ihre Elemente von Links, Rechts, Oben oder Unten einspielt oder mit fadeIn/Out einblendet. Die Slideshow ist dank width:100% responsive, wenn für img im CSS img { width: 100%, height: auto} gesetzt ist.

Das Slideshow-Script

Das Script ist genauso kurz:

function startSlideshow(selector, options = {}) {
  const container = document.querySelector(selector);
  const slides = container.querySelectorAll(".slides figure");
  const nextBtn = container.querySelector(".next");
  const prevBtn = container.querySelector(".prev");

  const direction = options.direction || "fade"; // "fade", "left", "top", etc.
  const duration = options.duration || 3000;
  const autoplay = options.autoplay !== false;

  let index = 0;
  let timer;

  const directions = {
    left: "translateX(-100%)",
    right: "translateX(100%)",
    top: "translateY(-100%)",
    bottom: "translateY(100%)",
  };

  function showSlide(newIndex, reverse = false) {
    slides.forEach((slide, i) => {
      slide.classList.remove("active");
      slide.style.transition = "none";
      slide.style.opacity = "0";
      slide.style.transform = "translate(0, 0)";
      slide.style.zIndex = 0;
    });

    const prevSlide = slides[index];
    const nextSlide = slides[newIndex];

    if (direction !== "fade") {
      const dir = directions[direction] || "translateX(100%)";
      nextSlide.style.transform = reverse
        ? dir.replace("100%", "-100%")
        : dir;

      nextSlide.style.transition = "";
      requestAnimationFrame(() => {
        nextSlide.classList.add("active");
        nextSlide.style.transform = "translate(0, 0)";
        nextSlide.style.opacity = "1";
      });

      prevSlide.style.transition = "transform 1s ease, opacity 1s ease";
      prevSlide.style.transform = reverse
        ? dir.replace("-100%", "100%")
        : dir;
    } else {
      nextSlide.classList.add("active");
      nextSlide.style.opacity = "1";
    }

    index = newIndex;
  }

  function nextSlide() {
    const newIndex = (index + 1) % slides.length;
    showSlide(newIndex);
  }

  function prevSlide() {
    const newIndex = (index - 1 + slides.length) % slides.length;
    showSlide(newIndex, true);
  }

  nextBtn.addEventListener("click", () => {
    nextSlide();
    resetTimer();
  });

  prevBtn.addEventListener("click", () => {
    prevSlide();
    resetTimer();
  });

  function resetTimer() {
    if (autoplay) {
      clearInterval(timer);
      timer = setInterval(nextSlide, duration);
    }
  }

  showSlide(index);

  if (autoplay) {
    timer = setInterval(nextSlide, duration);
  }
}

Am Ende entscheidet ein einfaches Objekt über die Optionen der Slideshow: Wie sollen die Bilder einfliegen oder eingeblendet werden, wie lang soll jedes Bild gezeigt werden, soll die Slideshow einen automatischen Bilderwechsel durchführen.

startSlideshow("#slideshow", {
  direction: "fade",     // oder: "left", "right", "top", "bottom"
  duration: 5000,        // in ms
  autoplay: true         // oder false für manuelle Steuerung
});

Das Script ist einfach gehalten – es ist nur ein Einstieg. Die Arbeit wird vom CSS erledigt.

Slideshow als Javascript Object

Eine Slideshow mit Optionen ist aufwändiger, so dass sich ein Javascript-Object lohnt. Ein Slideshow-Object ist flexibler und lässt sich durch Optionen steuern.

Das CSS braucht nur eine kleine Änderung:

CSS für das Slideshow-Objekt

.slides {
	display:none;
	width: 100%;
	max-width: 620px;
	margin:1em auto;
}

.animate-top {
	display: block;
	position:relative;
	animation:animatetop 1s
}

@keyframes animatetop { 
  from { top:-300px; opacity: 0 } to { top:0; opacity:1 } 
}

Nach demselben Schema können weitere Animationen für den Übergang von einem Bild zum nächsten angelegt werden:

  • animate-top
  • animate-bottom
  • animate-left
  • animate-right
  • animate-zoom

Die Namen der Klassen werden gleich als Option in den Aufruf des Scripts eingesetzt.

Das HTML wird einen Tick einfacher, denn die Klassen für die CSS-Animation werden später beim Aufruf des Scripts als Option eingesetzt.

<div class="simpleSlides">
  <img class="slides" src="slide-1.jpg">
  <img class="slides" src="slide-2.jpg">
  <img class="slides" src="slide-3.jpg">
  <img class="slides" src="slide-4.jpg">
</div>

Lightbox-Script

const simpleSlides = function (options) {
    const Slideshow = {
    	init: function (options) {
    		this.count = 0;
    		this.slides = document.querySelectorAll(".slides");
    		this.numslides = this.slides.length;
    		options = options || {};
    		this.opts = {
    			speed:(typeof options.speed === "undefined") ? 3600 : options.speed,
    			animate:(typeof options.animate === "undefined") ? "animate-bottom" : options.animate
    		}
    		this.slides[0].classList.add(this.opts.animate);
    		this.autoCycle(this.opts.speed)
    	},
    	showSlide: function (i) {
    		if (i>0) {
    			this.count = (this.count + 1 === this.numslides) ? 0 : this.count + 1;
    		} else {
    			this.count = (this.count -1 < 0) ? this.numslides - 1 : this.count - 1;
    		}
    		document.querySelector("." + this.opts.animate).classList.remove(this.opts.animate);
    		this.slides[this.count].classList.add(this.opts.animate);
    	},
    	autoCycle: function (speed) {
    		const that = this,
    		interval = window.setInterval (function () {
    			that.showSlide(1);
    		},speed);
    	}
    }
    const slideshow = Object.create(Slideshow);
    console.log (slideshow)
    slideshow.init(options); 
}

const opts = {
	speed: 5000,
	animate: "animate-left"
}

simpleSlides(opts);

Object.create() erstellt eine neues Objekt. Diese Variante bietet den Freiraum, weitere Optionen aufzunehmen – z.B. ein "pause on hover".

Suchen auf mediaevent.de