'Vue.js slider with autoplay and controls
i created simple vue.js based slider. I have some problems with handling mouse actions such as play and pause. Main goal is to add progress bar on each slide control with the possibility of stopping and resuming timer for that current slide. Also each slide should be visible for example 2 seconds and you can change slide by clicking at this bar under the image. I have implemented some code but dont know how to reset that timer properly and create this animatig progress.
var app = new Vue({
el: '#app',
data () {
return {
delay: 2000,
activeIndex: 0,
handler: null,
isPlaying: true
}
},
methods: {
stop () {
this.isPlaying = false
console.log('stop')
clearTimeout(this.handler)
},
start () {
this.isPlaying = true
console.log('start')
},
handleClick (index) {
const slides = document.querySelectorAll('.slide')
const buttons = document.querySelectorAll('.button')
slides.forEach(slide => {
slide.classList.remove('active')
buttons.forEach(btn => {
btn.classList.remove('active')
})
})
this.activeIndex = index
slides[this.activeIndex].classList.add('active')
buttons[this.activeIndex].classList.add('active')
},
autoPlay () {
const slides = document.querySelectorAll('.slide')
const buttons = document.querySelectorAll('.button')
let active = document.getElementsByClassName('active')
const repeater = () => {
[...active].forEach(activeSlide => {
activeSlide.classList.remove('active')
})
slides[this.activeIndex].classList.add('active')
buttons[this.activeIndex].classList.add('active')
this.activeIndex++
if (slides.length === this.activeIndex) {
this.activeIndex = 0
}
if (this.activeIndex >= slides.length) {
return
}
this.handler = setTimeout(() => {
repeater()
}, this.delay)
}
repeater()
}
},
mounted () {
const buttons = document.querySelectorAll('.button')
buttons.forEach((button, index) => {
button.addEventListener('click', () => {
this.handleClick(index)
})
})
this.autoPlay()
}
})
#app {
min-height: 100px;
}
.slides {
position: relative;
height: 100px;
}
.slide {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100px;
opacity: 0;
color: #000;
}
.slide.active {
opacity: 1;
}
.controls {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.button {
appearance: none;
width: 40px;
height: 4px;
background-color: #000;
outline: none;
border: none;
margin: 0 10px;
}
.button.active {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="slider-wrapper">
<div class="slides">
<div class="slide active">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
</div>
<div class="controls">
<button class="toggler" @click="stop" v-if="isPlaying">stop</button>
<button class="toggler" @click="start" v-if="!isPlaying">start</button>
<button class="button active"></button>
<button class="button"></button>
<button class="button"></button>
</div>
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
