<div class="slider" data-autoplay="false" data-playing="false">
<div class="slider__inner">
<div class="slider__slides-wrap">
<div class="slider__slides">
<div class="slider__slide"><a class="card" href="#">
<div class="card__image">
<div class="image loading" style="padding-top: 100%;"><noscript><img class="image__fallback" alt="Alternativ-Text" width="610" height="610" src="https://via.placeholder.com/610x610/A0A0A6/FFFFFF.png?text=610x610" /></noscript><img class="image__img js-lazyload" alt="Alternativ-Text" width="610" height="610" data-src="https://via.placeholder.com/610x610/A0A0A6/FFFFFF.png?text=610x610" /></div>
</div>
<div class="card__play"><svg class="icon icon--play-box" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-play-box"></use>
</svg></div>
<div class="card__body">
<div class="card__body__inner">
<div class="card__headline">
<h2 class="headline headline--2">Heiling durch Gentherapie</h2>
</div>
<div class="card__subline">19.01.2021</div>
<div class="card__icons"><span class="card__icons__item"><svg class="icon icon--arrow-right" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-arrow-right"></use>
</svg></span></div>
</div>
</div>
</a></div>
<div class="slider__slide"><a class="microcard microcard--has-text" href="#">
<div class="microcard__inner">
<div class="microcard__image"><img class="microcard__image__img" src="https://via.placeholder.com/400x400/A0A0A6/ffffff.png?text=400x400" width="400" height="400" alt="Alternativ-Text" /></div>
<div class="microcard__bottom">
<div class="microcard__headline">
<h3 class="headline headline--3">Neue Partner: DASHH und HAW Hamburg</h3>
</div>
<div class="microcard__subline">19.01.2021</div>
<div class="microcard__text">220 Zeichen max. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam sed vitae harum dolore corrupti a molestias blanditiis, deserunt, nostrum nemo distinctio rerumess qui necessitatibus sequi laudantium ipsum.</div>
<div class="microcard__icons"><span class="microcard__icons__item"><svg class="icon icon--arrow-right" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-arrow-right"></use>
</svg></span></div>
</div>
</div>
</a></div>
<div class="slider__slide"><a class="microcard microcard--has-text" href="#">
<div class="microcard__inner">
<div class="microcard__image"><img class="microcard__image__img" src="https://via.placeholder.com/400x400/A0A0A6/ffffff.png?text=400x400" width="400" height="400" alt="Alternativ-Text" /></div>
<div class="microcard__bottom">
<div class="microcard__headline">
<h3 class="headline headline--3">Neue Partner: DASHH und HAW Hamburg</h3>
</div>
<div class="microcard__subline">19.01.2021</div>
<div class="microcard__text">220 Zeichen max. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam sed vitae harum dolore corrupti a molestias blanditiis, deserunt, nostrum nemo distinctio rerumess qui necessitatibus sequi laudantium ipsum.</div>
<div class="microcard__icons"><span class="microcard__icons__item"><svg class="icon icon--arrow-right" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-arrow-right"></use>
</svg></span></div>
</div>
</div>
</a></div>
<div class="slider__slide"><a class="microcard microcard--has-text" href="#">
<div class="microcard__inner">
<div class="microcard__image"><img class="microcard__image__img" src="https://via.placeholder.com/400x400/A0A0A6/ffffff.png?text=400x400" width="400" height="400" alt="Alternativ-Text" /></div>
<div class="microcard__bottom">
<div class="microcard__headline">
<h3 class="headline headline--3">Neue Partner: DASHH und HAW Hamburg</h3>
</div>
<div class="microcard__subline">19.01.2021</div>
<div class="microcard__text">220 Zeichen max. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam sed vitae harum dolore corrupti a molestias blanditiis, deserunt, nostrum nemo distinctio rerumess qui necessitatibus sequi laudantium ipsum.</div>
<div class="microcard__icons"><span class="microcard__icons__item"><svg class="icon icon--arrow-right" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-arrow-right"></use>
</svg></span></div>
</div>
</div>
</a></div>
<div class="slider__slide"><a class="microcard microcard--has-text" href="#">
<div class="microcard__inner">
<div class="microcard__image"><img class="microcard__image__img" src="https://via.placeholder.com/400x400/A0A0A6/ffffff.png?text=400x400" width="400" height="400" alt="Alternativ-Text" /></div>
<div class="microcard__bottom">
<div class="microcard__headline">
<h3 class="headline headline--3">Neue Partner: DASHH und HAW Hamburg</h3>
</div>
<div class="microcard__subline">19.01.2021</div>
<div class="microcard__text">220 Zeichen max. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam sed vitae harum dolore corrupti a molestias blanditiis, deserunt, nostrum nemo distinctio rerumess qui necessitatibus sequi laudantium ipsum.</div>
<div class="microcard__icons"><span class="microcard__icons__item"><svg class="icon icon--arrow-right" viewBox="0 0 200 200" role="presentation">
<use xlink:href="#icon-arrow-right"></use>
</svg></span></div>
</div>
</div>
</a></div>
</div>
</div>
</div>
</div>
//- Render slider
#{tag || 'div'}.slider(
data-autoplay=autoplay && 'true' || 'false',
data-playing=autoplay && 'true' || 'false',
)&attributes(attr)
.slider__inner: .slider__slides-wrap
if slides
.slider__slides
each item in slides
.slider__slide
+include(`@${item.use}`, item.settings || {})
{
"slides": [
{
"use": "card--news"
},
{
"use": "microcard--news"
},
{
"use": "microcard--news"
},
{
"use": "microcard--news"
},
{
"use": "microcard--news"
}
]
}
import { lory } from '@rsm/allfarblori';
import h from 'hyperscript';
import icon from 'components/_particles/icon/generate-icon';
export default class Slider {
constructor($el) {
this.$el = $el;
this.$slides = this.$el.querySelectorAll('.slider__slide');
this.$inner = this.$el.querySelector('.slider__inner');
this.$slidesContainer = this.$el.querySelector('.slider__slides-wrap');
// Don't init slider, if only one slide exists
if (this.$slides.length === 1) {
return;
}
this.$el.addEventListener('before.lory.init', () => {
this.$slidesContainer.scrollLeft = 0;
this.initControls();
});
this.$el.addEventListener('after.lory.init', () => {
window.console.log('[Slider] Initialized', $el);
this.$el.classList.add('slider--initialized');
this.initAutoplay();
});
this.$el.addEventListener('after.lory.slide', () => {
window.console.log('[Slider] Slide', $el);
this.updateDots();
this.updatePagination();
});
this.lory = lory(this.$el, {
rewind: true,
slideSpeed: 250,
ease: 'cubic-bezier(0.455, 0.03, 0.515, 0.955)',
classNameFrame: 'slider__slides-wrap',
classNameSlideContainer: 'slider__slides',
classNamePrevCtrl: 'slider__arrow--prev',
classNameNextCtrl: 'slider__arrow--next',
classNameDisabledPrevCtrl: 'slider__arrow--disabled',
classNameDisabledNextCtrl: 'slider__arrow--disabled',
});
this.$slidesContainer.addEventListener('focusin', (event) => {
this.$slidesContainer.scrollLeft = 0;
const $slide = event.target.closest('.slider__slide');
const index = Array.prototype.indexOf.call(this.$slides, $slide);
this.lory.slideTo(index);
});
}
initControls() {
this.$controlPrev = h(
'button.slider__arrow.slider__arrow--prev',
{
type: 'button',
tabIndex: '-1',
title: 'Vorheriger Slide',
},
icon({
icon: 'arrow-left-box',
className: 'slider__arrow-icon',
}),
h('span.u-hidden-visually', 'Vorheriger Slide'),
);
this.$controlNext = h(
'button.slider__arrow.slider__arrow--next',
{
type: 'button',
tabIndex: '-1',
title: 'Nächster Slide',
},
icon({
icon: 'arrow-right-box',
className: 'slider__arrow__icon',
}),
h('span.u-hidden-visually ', 'Nächster Slide'),
);
this.$dots = h(
'.slider__dots',
[...this.$slides].map((_, index) => h(
`button.slider__dots__dot${index === 0 ? '.slider__dots__dot--active' : ''}`,
{
type: 'button',
tabIndex: '-1',
title: (index + 1),
onclick: () => this.lory.slideTo(index),
},
h('span.u-hidden-visually', (index + 1)),
)),
);
this.$pagination = h(
'.slider__pagination',
h('span.u-hidden-visually', 'Aktuelle Seite'),
h('span.slider__pagination__current-page', '1'),
'/',
h('span.u-hidden-visually', 'Seitenanzahl'),
h('span.slider__pagination__total-page-count', this.$slides.length),
);
this.$controlPlay = h(
'button.slider__play-control',
{
type: 'button',
title: 'Slides automatisch abspielen',
attrs: {
'aria-pressed': this.isAutoplay() ? 'true' : 'false',
},
}, icon({
icon: 'play',
className: 'slider__play-control__icon slider__play-control__icon--play',
}), icon({
icon: 'pause',
className: 'slider__play-control__icon slider__play-control__icon--stop',
}),
h('span.u-hidden-visually', 'Slides automatisch abspielen'),
);
this.$controls = h('.slider__controls');
this.$controls.appendChild(this.$controlPrev);
this.$controls.appendChild(this.$controlPlay);
this.$controls.appendChild(this.$pagination);
this.$controls.appendChild(this.$dots);
this.$controls.appendChild(this.$controlNext);
this.$inner.appendChild(this.$controls);
}
isPlaying() {
return (this.$el.getAttribute('data-playing') === 'true');
}
isAutoplay() {
return (this.$el.getAttribute('data-autoplay') === 'true');
}
initAutoplay() {
// Touch kill
let hasTouched = false;
// Init timer
const timerInit = () => setInterval(() => this.lory.next(), 5000);
let timer = this.isPlaying() ? timerInit() : false;
// Kill timer if a mouse enters the slider
this.$el.addEventListener('mouseover', () => {
// this.$el.setAttribute('data-playing', 'false');
clearInterval(timer);
});
// Restart timer if a mouse leaves the slider
this.$el.addEventListener('mouseleave', () => {
if (!hasTouched && this.isPlaying()) timer = timerInit();
});
// Kill the timer if at least on touch interaction happend
this.$el.addEventListener('touchstart', function killOnTouchStart() {
clearInterval(timer);
this.$el.revomeEventListener('touchstart', killOnTouchStart);
hasTouched = true;
}, { passive: true });
// Autoplay toggle button (play/pause)
this.$controlPlay.addEventListener('click', () => {
if (this.isPlaying()) {
this.$controlPlay.setAttribute('aria-pressed', 'false');
this.$el.setAttribute('data-playing', 'false');
clearInterval(timer);
} else {
this.$controlPlay.setAttribute('aria-pressed', 'true');
this.$el.setAttribute('data-playing', 'true');
if (!hasTouched) timer = timerInit();
setTimeout(() => this.lory.next(), 500);
}
});
}
updateDots() {
this.$el.querySelector('.slider__dots__dot--active')
.classList.remove('slider__dots__dot--active');
this.$el.querySelectorAll('.slider__dots__dot')[this.lory.returnIndex()]
.classList.add('slider__dots__dot--active');
}
updatePagination() {
this.$el.querySelector('.slider__pagination__current-page').innerHTML = this.lory.returnIndex() + 1;
this.$el.querySelector('.slider__pagination__total-page-count').innerHTML = this.$slides.length;
}
}
document.querySelectorAll('.slider').forEach($slider => new Slider($slider));
// Slider
.slider {
position: relative;
width: 100%;
}
.slider__inner {
position: relative;
}
.slider__slides-wrap {
position: relative;
width: 100%;
.no-js & {
overflow-x: scroll;
overflow-y: hidden;
}
.slider--initialized & {
overflow: visible;
}
}
.slider__slides {
display: flex;
transition-property: transform;
z-index: 1;
}
// Single Slide
.slider__slide {
flex-shrink: 0;
position: relative;
transition: opacity 0.35s;
width: 100%;
@include mq($from: m) {
flex-shrink: 1;
padding-right: 4rem;
}
}
// Arrows
.slider__arrow {
color: #fff;
cursor: pointer;
font-size: 1.6rem;
height: 4rem;
// opacity: 0;
// pointer-events: none;
position: absolute;
top: 45%;
transform: translateY(-50%);
transition: 0.2s;
transition-property: opacity;
width: 4rem;
z-index: 2;
@include mq($until: xl) {
display: none;
}
}
.slider__arrow .icon {
color: $color-dark;
cursor: pointer;
height: 5.2rem;
left: 50%;
opacity: 0.5;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 5.2rem;
}
.slider__arrow--prev .icon {
cursor: pointer;
left: 46%;
}
.slider__arrow--disabled {
opacity: 0;
pointer-events: none;
}
.slider__arrow--prev {
left: -6.5rem;
}
.slider__arrow--next {
right: 2.5rem;
@include mq($from:xxl) {
right: 4.5rem;
}
}
// Dots
.slider__dots {
bottom: -5rem;
display: inline-block;
left: 50%;
position: absolute;
transform: translateX(-50%);
&__dot {
background: $color-gray;
border-radius: 0.35rem;
display: inline-block;
height: 0.7rem;
margin: 0 0.5rem;
transition: background 0.2s, width 0.2s;
width: 0.7rem;
}
&__dot--active {
background: $color-dark;
width: 3rem;
}
}
// Pagination
.slider__pagination {
display: none;
}
// Play Control
.slider__play-control {
display: none;
}
// Custom styles
.slider .card {
@include mq($from: m) {
margin-right: 4rem;
}
}
.slider .microcard {
@include mq($until: m) {
margin: 0 2rem;
width: calc(100% - 4rem);
}
}
There are no notes for this item.