Slider

  • horizontal Slidert

    • IMG_6867
    • IMG_6868
    • IMG_6869
    • IMG_6870
    • IMG_6871
    • IMG_6872
  • vertical Slider

    • IMG_6867
    • IMG_6868
    • IMG_6869
    • IMG_6870
    • IMG_6871
    • IMG_6872

Slider auf JavaScript Basis habe ich schon einige geschrieben, nun aber versuche ich es mit einem anderen Ansatz, für das Sliden möchte ich das über CSS gestaltete Scrollen nutzen, dadurch ist die Umsetzung der Touch- und Wheel-Events nicht erforderlich, da es im Standard schon funktioniert.

Als Methoden zur Animierung sollen dann zusätzlich zum Wischen und Mousewheel/Mouspad (2-Finger), noch Pfeile (vorwärts/rückwärts), Bubbes (Punkte zur Steuerung und Anzeige aktiver Slide) oder Thumbnails (Bilder zur Steuerung und Anzeige aktiver Slide) und eine Autoplay Funktion (optional mit Play & Pause Button).

Das Sliden soll in horzontaler aber auch vertikaler Richtung funktionieren.

Es ist klar das hierbei alte Browser nicht so einfach berücksichtigt werden können, aber schauen wir mal was geht.

HTML:
flex-slider.htm HTML (1,27 kByte) 20.04.2021 19:17
<!DOCTYPE html >
<html lang="de">
  <head>
    <meta charset="utf-8" />
    <title>Slider</title>
    <link rel="stylesheet" href="../tabsheet.css" />
  </head>
  <body>
    <ul class="tabsheets">
      <li class="active">
        <h4 class="sheet-header">horizontal Slidert</h4>
        <div class="flex-slider" data-options="thumbs arrows autoplay play&pause">
          <ul>
            <li><img src="IMG_6867.jpg" /></li>
            <li><img src="IMG_6868.jpg" /></li>
            <li><img src="IMG_6869.jpg" /></li>
            <li><img src="IMG_6870.jpg" /></li>
            <li><img src="IMG_6871.jpg" /></li>
            <li><img src="IMG_6872.jpg" /></li>
          </ul>
        </div>
      </li>
      <li>
        <h4 class="sheet-header">vertical Slider</h4>
        <div class="flex-slider vertical" data-options="thumbs arrows autoplay">
          <ul>
            <li><img src="IMG_6867.jpg" /></li>
            <li><img src="IMG_6868.jpg" /></li>
            <li><img src="IMG_6869.jpg" /></li>
            <li><img src="IMG_6870.jpg" /></li>
            <li><img src="IMG_6871.jpg" /></li>
            <li><img src="IMG_6872.jpg" /></li>
          </ul>
        </div>
      </li>
    </ul>
    <script src="../tabsheet.js"></script>
    <script src="flex-slider.js"></script>
  </body>
</html>
JavaScript:
flex-slider.js JavaScript (6,59 kByte) 21.04.2021 14:24
// coding: utf-8
/** Created by: Udo Schmal | https://www.gocher.me/ */
(function() {
  'use strict';
  // scroll into parent view
  Element.prototype.scrollIntoParentView = function () {
    this.parentNode.scrollTo({top: this.offsetTop, left: this.offsetLeft, behavior: 'smooth'});
  };
  function Slider(el) {
    var slider = el; // slider div
    var slides = el.querySelector('ul'); // slides ul list
    if (!slides.classList.contains('slides')) {
      slides.classList.add('slides');
    }
    var items = slides.children; // slides li items
    var controls = null; // bubbles/thumbs ul list
    var controlItems = []; // bubbles/thumbs li items
    var prev = null; // previous div button
    var next = null; // next div button
    var play = null; // play & pause div button
    var active = 0; // active slide position counter

    // load stylesheet
    if (!document.getElementById('flex-slider.css')) {
      var style = document.createElement("link");
      style.type = 'text/css';
      style.href = '/code/flex-slider/flex-slider.css';
      style.id = 'flex-slider.css';
      style.rel = 'stylesheet';
      document.head.appendChild(style);
    }
    // get settings from dom
    var direction = el.classList.contains('vertical') ? 'vertical' : 'horizontal';
    if ((direction == 'horizontal') && !el.classList.contains('horizontal')) {
      el.classList.add('horizontal');
    }
    var thumbs = false, bubbles = false, autoplay = false, arrows = false, playpause = false;
    if (el.dataset.options) {
      thumbs = el.dataset.options.indexOf('thumbs') !== -1;
      bubbles = el.dataset.options.indexOf('bubbles') !== -1;
      autoplay = el.dataset.options.indexOf('autoplay') !== -1;
      arrows = el.dataset.options.indexOf('arrows') !== -1;
      playpause = el.dataset.options.indexOf('play&pause') !== -1;
    }
    // slide & snap
    function startScroll() {
      for (let i = 0; i < items.length; i++) {
        items[i].classList.remove('active');
        if (controls) {
          controlItems[i].classList.remove('active');
        }
      }
    }
    function stopScroll() {
      scrollTimer = null;
      for (let i = 0; i < items.length; i++) {
        if ((Math.abs(slides.scrollTop - items[i].offsetTop) < 5) &&
            (Math.abs(slides.scrollLeft - items[i].offsetLeft) < 5)) {
          if (controls) {
            controlItems[i].classList.add('active');
          }
          items[i].classList.add('active');
          active = i;
        }
      }
      if (prev) {
        if (active == 0) {
          prev.classList.add('hidden');
        } else {
          prev.classList.remove('hidden');
        }
      }
      if (next) {
        if (active == items.length-1) {
          next.classList.add('hidden');
        } else {
          next.classList.remove('hidden');
        }
      }
    }
    var scrollTimer;
    function sliderScroll(event) {
      if (scrollTimer) {
        clearTimeout(scrollTimer);
      } else {
        startScroll();
      }
      scrollTimer = setTimeout(stopScroll, 20);
    }
    slides.addEventListener('scroll', sliderScroll);

    // auto slide
    var slideshow = null;
    var restartTimer;
    function startSlideshow () {
      if (restartTimer) {
        clearTimeout(restartTimer);
      }
      if (!slideshow) {
        slideshow = window.setInterval(function () {
          if (active+1 < items.length) {
            items[++active].scrollIntoParentView();
          } else {
            items[0].scrollIntoParentView();
          }
        }, 3000);
      }
    }
    function stopSlideShow () {
      if (slideshow) {
        window.clearInterval(slideshow);
        slideshow = null;
      }
    }
    function pauseSlideshow () {
      if (slideshow) {
        window.clearInterval(slideshow);
        slideshow = null;
        restartTimer = setTimeout(startSlideshow, 5000);
      };
    }
    function toggleSlideshow () {
      if (play.classList.contains('play')) {
        startSlideshow();
        play.classList.remove('play');
        play.classList.add('pause');
      } else {
        stopSlideShow();
        play.classList.remove('pause');
        play.classList.add('play');
      }
    }
    if (autoplay) {
      startSlideshow();
      // mousepad, wheel scroll
      el.addEventListener('wheel', pauseSlideshow, true);
      // touch screen
      el.addEventListener('touch', pauseSlideshow, true);
      el.addEventListener('touchstart', pauseSlideshow, true);
      el.addEventListener('touchend', pauseSlideshow, true);
      el.addEventListener('touchmove', pauseSlideshow, true);
      el.addEventListener('touchcancel', pauseSlideshow, true);
    }
    // play & pause button
    if (playpause) {
      play = document.createElement('div');
      play.className = autoplay ? 'pause' : 'play';
      play.addEventListener('click', toggleSlideshow);
      el.appendChild(play);
    }

    // control bubbles
    if (bubbles || thumbs) {
      controls = document.createElement('ul');
      controls.classList.add('controls');
      controls.classList.add(thumbs ? 'thumbs' : 'bubbles');
      el.appendChild(controls);
      function controlClick(event) {
        if (autoplay) {
          pauseSlideshow();
        }
        this.slide.scrollIntoParentView();
      }
      for(let i = 0; i < items.length; i++) {
        let li = document.createElement('li');
        li.slide = items[i];
        if (thumbs) {
          let img = items[i].querySelector('img');
          if (img) {
            if (img.src) {
              li.style.backgroundImage = 'url("' + img.src + '")';
            } else if (img.dataset.src) {
              li.style.backgroundImage = 'url("' + img.dataset.src + '")';
            }
          }
        }
        li.addEventListener('click', controlClick);
        controls.appendChild(li);
      }
      controlItems = controls.children;
      controlItems[active].classList.add('active');
    }

    // previous & next button
    if (arrows) {
      prev = document.createElement('div');
      prev.className = 'prev';
      function prevClick() {
        if (autoplay) {
          pauseSlideshow();
        }
        items[--active].scrollIntoParentView();
      }
      prev.addEventListener('click', prevClick);
      el.appendChild(prev);

      next = document.createElement('div');
      next.className = 'next';
      function nextClick() {
        if (autoplay) {
          pauseSlideshow();
        }
        items[++active].scrollIntoParentView();
      }
      next.addEventListener('click', nextClick);
      el.appendChild(next);
    }

  }
  var els = document.querySelectorAll('.flex-slider'), cnt = els.length, i;
  for (i=0; i < cnt; i++) {
    new Slider(els[i]);
  }
})();
StyleSheet:
flex-slider.css StyleSheet (3,89 kByte) 21.04.2021 14:38
.flex-slider {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 0;
  min-height: 1px;
  padding-top: 44%;
}
.flex-slider > .slides {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 0;
  list-style-type: none;
  scroll-behavior: smooth;
  /*overflow-scrolling: auto;*/
  /* hide IE scrollbar */
  -ms-overflow-style: none;
}
/* hide WebKit scrollbar */
.flex-slider > .slides::-webkit-scrollbar {
  display: none;
}
.flex-slider.horizontal > .slides {
  bottom: -12px; /* scrollbar fix */
  display: flex;
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  overflow-y: hidden;
}
.flex-slider.vertical > .slides {
  right: -12px; /* scrollbar fix */
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
  overflow-x: hidden;
}
.flex-slider .slides > li {
  position: relative;
  margin: 0;
  padding: 0;
  scroll-snap-align: start;
}
.flex-slider.horizontal .slides > li {
  width: 100%;
  height: auto;
  display: inline-block;
  flex-shrink: 0;
}
.flex-slider.vertical .slides > li {
  height: 100%;
  width: auto;
}
.flex-slider > .slides > li > img {
  width: 100%;
  height: auto;
}

.flex-slider > .controls {
  right: 0;
}
.flex-slider.horizontal > .controls {
  position: absolute;
  left: 0;
  bottom: 15px;
  text-align: center;
}
.flex-slider.vertical > .controls {
  position: absolute;
  top: 50%;
  right: 25px;
  transform: translate(0, -50%);
  display: block;
}
.flex-slider.vertical > .controls::after {
  display: table;
  content: '';
  clear: both;
}
.flex-slider.horizontal > .controls.thumbs {
  height: 10%;
}
.flex-slider.vertical > .controls.thumbs {
  width: 10%;
}
.flex-slider > .controls > li {
  display: inline-block;
  outline: none;
  background-color: #fff;
  opacity: 0.8;
  cursor: pointer;
}
.flex-slider.horizontal > .controls > li {
  display: inline-block;
  margin: 0 5px;
}
.flex-slider.vertical > .controls > li {
  display: block;
  margin: 5px 0;
}

.flex-slider > .controls.bubbles > li {
  border: 1px solid #000;
  transition: border 500ms ease-out;
  width: 0.85em;
  height: 0.85em;
  border-radius: 50%;
}
.flex-slider > .controls.thumbs > li {
  border: 2px solid #000;
  transition: border 500ms ease-out;
}
.flex-slider > .controls.bubbles > li.active {
  background-color: #000;
}
.flex-slider > .controls.thumbs > li.active {
  border-color: #fff;
}
.flex-slider > .controls.thumbs > li {
  position: relative;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}
.flex-slider.horizontal > .controls.thumbs > li {
  width: 10%;
  height: 100%;
}
.flex-slider.vertical > .controls.thumbs > li {
  padding-top: 44%;
  width: 100%;
}

.flex-slider > .prev, .flex-slider > .next, .flex-slider > .play, .flex-slider > .pause {
  cursor: pointer;
  position: absolute;
}
.flex-slider.horizontal > .prev, .flex-slider.horizontal > .next {
  top: 50%;
  transform: translate(0, -50%);
}
.flex-slider.vertical > .prev, .flex-slider.vertical > .next {
  left: 50%;
  transform: translate(-50%, 0);
}
.flex-slider.horizontal > .prev {
  left: 15px;
}
.flex-slider.horizontal > .next {
  right: 15px;
}
.flex-slider.vertical > .prev {
  top: 15px;
}
.flex-slider.vertical > .next {
  bottom: 15px;
}
.flex-slider > .prev.hidden, .flex-slider > .next.hidden {
  display: none;
}
.flex-slider > .prev::after, .flex-slider > .next::after, .flex-slider > .play::after, .flex-slider > .pause::after {
  display: inline-block;
  color: #fff;
  font-size: 2em;
}
.flex-slider.horizontal > .prev::after {
  content: '\140a';
}
.flex-slider.horizontal > .next::after {
  content: '\1405';
}
.flex-slider.vertical > .prev::after {
  content: '\1403';
}
.flex-slider.vertical > .next::after {
  content: '\1401';
}

.flex-slider > .play, .flex-slider > .pause {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.flex-slider:hover > .play::after {
  content: '\23EF';
}
.flex-slider:hover > .pause::after {
  content: '\23f8';
}

Author: , published: , last modified:

Kontakt

Udo Schmal

Udo Schmal
Softwareentwickler
Olvengraben 41
47608 Geldern
Nordrhein-Westfalen
Germany





+49 2831 9776557
+49 1575 0663676
+49 2831 1328709
SMS
WhatsApp

Instagram Profile
vCard 3.0

Service Infos

CMS Info Product Name:
UDOs Webserver
Version:
0.5.0.58
Description:
All in one Webserver
Copyright:
Udo Schmal
Compilation:
Sat, 17. Apr 2021 17:15:14
Development Info Compiler:
Free Pascal FPC 3.3.1
compiled for:
OS:Linux, CPU:x86_64
System Info OS:
Ubuntu 20.04.2 LTS (Focal Fossa)
Hardware Info Model:
Hewlett-Packard HP Pavilion dv7 Notebook PC
CPU Name:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
CPU Type:
x86_64, 1 physical CPU(s), 2 Core(s), 4 logical CPU(s), 2893.370 MHz