I'm making a photo slider using HTML, CSS and JS. It has an autoplay function, navigation arrows and dots. The direction of the slide animation is reversed based on the corresponding arrows/dots, and the timer is reset on each slide. I'm currently trying to add a "pause on hover" function, but it doesn't pause the timer but resets the timer.
For example, the slider speed is currently set to 3000ms. When the cursor hovers over .elements
at 2000ms, I need it to pause the timer. And when the cursor leaves .elements
, I need the timer to count down the remaining 1000ms and then move on to the next slide. Could you please help me with this?
var timeout;
function setDirection(d) {
document.querySelector('.slider').style.setProperty('--direction', d);
}
setDirection(1);
var slider = document.getElementsByClassName("slider")[0];
var sliderDots = Array.prototype.slice.call(document.getElementsByClassName("dots")[0].children);
var sliderContents = Array.prototype.slice.call(document.getElementsByClassName("elements")[0].children);
var sliderArrowLeft = document.getElementsByClassName("arrow-left")[0];
var sliderArrowRight = document.getElementsByClassName("arrow-right")[0];
var sliderSpeed = 3000,
currentSlide = 0,
currentActive = 0,
sliderTimer = 0;
let elements = document.querySelector('.elements');
elements.addEventListener('mouseover', function() {
clearTimeout(sliderTimer);
});
elements.addEventListener('mouseout', function() {
playSlide(currentSlide);
});
function playSlide(slide, d) {
if (!(d === undefined)) {
direction = d;
setDirection(d);
// Force it forwards after it's done:
clearTimeout(timeout);
timeout = setTimeout(function() {
setDirection(1);
}, 1000)
}
for (var k = 0; k < sliderDots.length; k++) {
sliderContents[k].classList.remove("active");
sliderContents[k].classList.remove("inactive");
sliderDots[k].classList.remove("active");
}
if (slide < 0) {
slide = currentSlide = sliderContents.length - 1;
}
if (slide > sliderContents.length - 1) {
slide = currentSlide = 0;
}
if (currentActive != currentSlide) {
sliderContents[currentActive].classList.add("inactive");
}
sliderContents[slide].classList.add("active");
sliderDots[slide].classList.add("active");
currentActive = currentSlide;
clearTimeout(sliderTimer);
sliderTimer = setTimeout(function() {
playSlide(currentSlide += 1);
}, sliderSpeed)
}
sliderArrowLeft.addEventListener("click", function() {
playSlide(currentSlide -= 1, -1);
})
sliderArrowRight.addEventListener("click", function() {
playSlide(currentSlide += 1, 1);
})
for (var l = 0; l < sliderDots.length; l++) {
sliderDots[l].addEventListener("click", function() {
let d = sliderDots.indexOf(this) - currentSlide
playSlide(currentSlide = sliderDots.indexOf(this), Math.sign(d));
})
}
playSlide(currentSlide);
.slider {
overflow: hidden;
position: relative;
}
.contents {
width: 100%;
height: 200px;
position: relative;
overflow: hidden;
}
.arrow-left,
.arrow-right {
width: 50px;
height: 50px;
bottom: 0;
cursor: pointer;
display: block;
text-align: center;
line-height: 50px;
background: rgb(200, 200, 200);
position: absolute;
z-index: 2;
}
.arrow-left {
left: 0;
}
.arrow-right {
right: 0;
}
.dots {
height: 14px;
bottom: 0;
left: 50%;
font-size: 0;
text-align: right;
position: absolute;
z-index: 2;
transform: translateX(-50%);
}
.dot {
width: 12px;
height: 12px;
margin-left: 5px;
margin-right: 5px;
display: inline-block;
cursor: pointer;
border-style: solid;
border-width: 1px;
border-color: rgb(100, 100, 100);
}
.dot.active {
background: rgb(200, 200, 200);
}
.elements {
width: 100%;
overflow: hidden;
transform: translate(0px);
}
.image {
width: 100%;
height: 100px;
top: 0;
position: absolute;
opacity: 0;
}
.image span {
width: 100%;
height: 100px;
text-align: center;
line-height: 100px;
display: block;
background: rgb(200, 200, 200);
}
.image.active {
position: relative;
z-index: 1;
opacity: 1;
}
.image.inactive {
z-index: -3;
opacity: 1;
}
.image.active span {
animation: show .5s ease-in-out forwards;
}
.image.inactive span {
animation: hide .5s ease-in-out forwards;
}
@keyframes show {
0% {
transform: translateX(calc(var(--direction)*100%));
}
100% {
transform: translateX(0);
}
}
@keyframes hide {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(calc(-1*var(--direction)*100%));
}
}
<div class="slider">
<div class="contents">
<div class="arrow-left">prev</div>
<div class="arrow-right">next</div>
<div class="dots">
<li class="dot"></li>
<li class="dot"></li>
<li class="dot"></li>
</div>
<div class="elements">
<div class="image"><span>image 1</span></div>
<div class="image"><span>image 2</span></div>
<div class="image"><span>image 3</span></div>
</div>
</div>
</div>