hella-slider
Version:
Hella rad image slider.
134 lines • 5.46 kB
JavaScript
class HellaSlider {
constructor(breakpoint = 900, selector = '.hella-slider') {
if (document.querySelector(selector)) {
this.breakpoint = breakpoint
this.sel = {
slider: selector, sliderImages: '.hella-slider-images',
captionSlot: '.hella-caption-display-slot', prevButton: '.hella-slider-prev',
nextButton: '.hella-slider-next', disabledClass: 'hella-disabled',
transitionClass: 'hella-smooth-transition'
}
this.xDown = this.yDown = null
this.init(document.querySelectorAll(this.sel.slider))
}
}
init(sliderConts) {
sliderConts.forEach(s => {
s.setAttribute('count', 0)
s.querySelector(this.sel.prevButton).classList.add(this.sel.disabledClass)
s.initialWidth = s.style.width
let figures = this.initFigures(s)
let thisCaption = figures[0].querySelectorAll('figcaption')[0]
let thisSlot = s.querySelector(this.sel.captionSlot)
if (thisSlot && thisCaption) {
thisSlot.innerHTML = thisCaption.innerHTML
}
s.querySelector(this.sel.prevButton).addEventListener('click', e => this.moveSlide(s, 'prev'))
s.querySelector(this.sel.nextButton).addEventListener('click', e => this.moveSlide(s, 'next'))
s.addEventListener('touchstart', e => this.touchStart(e))
s.addEventListener('touchmove', e => this.touchMove(s, e))
window.addEventListener('resize', e => this.initFigures(s, e))
})
}
initFigures(s, e) {
if (document.body.clientWidth < this.breakpoint) {
s.style.width = 'auto'
} else {
s.style.width = s.initialWidth
}
let figures = s.querySelectorAll('figure')
figures.forEach(f => {
f.style.width = s.clientWidth + 'px'
f.children[0].style.opacity = 1
})
if (e !== undefined && e.type === 'resize') {
let c = s.getAttribute('count')
s.querySelector(this.sel.sliderImages).classList.remove(this.sel.transitionClass)
s.querySelector(this.sel.sliderImages).style.marginLeft =
figures[0].clientWidth * -c + 'px'
}
return figures
}
touchStart(e) {
this.xDown = e.touches[0].clientX
this.yDown = e.touches[0].clientY
}
touchMove(s, e) {
if (!this.xDown || !this.yDown) {
return
}
let xUp = e.touches[0].clientX
let yUp = e.touches[0].clientY
let xDiff = this.xDown - xUp
let yDiff = this.yDown - yUp
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (xDiff > 0) {
this.moveSlide(s, 'next')
} else {
this.moveSlide(s, 'prev')
}
}
this.xDown = null
this.yDown = null
}
moveSlide(sliderCont, dir) {
let s = this.parseElement(sliderCont)
if (!s.sliderImageContainer.classList.contains(this.sel.transitionClass)) {
s.sliderImageContainer.classList.add(this.sel.transitionClass)
}
if (dir === 'prev') {
if (s.sliderCount === 0) {
return
}
this.diff = s.marginLeftInt + s.currentFigureWidth + 'px'
}
if (dir === 'next') {
if (s.sliderCount === 0) {
s.sliderPrevButton.classList.remove(this.sel.disabledClass)
}
if (s.figures.length - 1 === s.sliderCount) {
return
}
this.diff = s.marginLeftInt - s.currentFigureWidth + 'px'
}
s.sliderImageContainer.style.marginLeft = this.diff
this.setCaptionAndCount(s, dir)
}
setCaptionAndCount(s, dir) {
let el = dir === 'prev' ? s.figures[s.sliderCount - 1] : s.figures[s.sliderCount + 1]
let figCaption = el.getElementsByTagName('figcaption')[0]
if (s.slot) {
s.slot.innerHTML = figCaption ? figCaption.innerHTML : ''
}
let newValue = dir === 'prev' ? s.sliderCount - 1 : s.sliderCount + 1;
s.sliderCont.setAttribute('count', newValue)
if (dir === 'prev') {
if (s.sliderCount - 1 === 0) {
s.sliderPrevButton.classList.add(this.sel.disabledClass)
}
if (s.sliderCount - 1 !== s.figures.length) {
s.sliderNextButton.classList.remove(this.sel.disabledClass)
}
}
if (dir === 'next') {
if (s.sliderCount + 1 === s.figures.length - 1) {
s.sliderNextButton.classList.add(this.sel.disabledClass)
}
}
}
parseElement(el) {
let s = {}
s.sliderCont = el
s.figures = el.querySelectorAll('figure')
s.sliderCount = parseInt(el.getAttribute('count'))
s.currentFigure = s.figures[s.sliderCount]
s.currentFigureWidth = parseInt(s.currentFigure.style.width)
s.sliderImageContainer = el.querySelector(this.sel.sliderImages)
s.marginLeftInt = parseInt(s.sliderImageContainer.style.marginLeft) || 0
s.slot = el.querySelector(this.sel.captionSlot)
s.sliderPrevButton = el.querySelector(this.sel.prevButton)
s.sliderNextButton = el.querySelector(this.sel.nextButton)
return s
}
}
new HellaSlider()