I’ve got this below code for an image slide show I have. It allows the user to both click arrows to scroll through images (this works perfectly), and if on a mobile device, swipe through the images. That said, for some reason, when my user swipes through the images, it skips an image (or sometimes 2!) It’s driving me mental.
It seems like when I do small swipes, the images are in the correct order. But if I do a larger swipe, it starts skipping images. I’ve tried eliminating the swipeDistance and changing the threshold size but nothing seems to work. Help!
Code:
<script>
(() => {
const images_list = [
{
"url": "https://www.url.com/image1.png",
"alt": "",
"name": "Image 1",
"link": ""
},
{
"url": "https://www.url.com/image2.png",
"alt": "",
"name": "",
"link": ""
},
{
"url": "https://www.url.com/image3.png",
"alt": "",
"name": "",
"link": ""
},
{
"url": "https://www.url.com/image4.png",
"alt": "",
"name": "",
"link": ""
}
];
let slider_id = document.querySelector("#accessory");
// append all images
let dots_div = "";
let images_div = "";
for (let i = 0; i < images_list.length; i++) {
let href = (images_list[i].link == "" ? "":' href="'+images_list[i].link+'"');
images_div += '<a'+href+' class="hcg-slides animated"'+(i === 0 ? ' style="display:flex"':'')+'>'+
'<img src="'+images_list[i].url+'" alt="'+images_list[i].name+'">'+
'</a>';
dots_div += '<a href="#" class="hcg-slide-dot'+(i === 0 ? ' dot-active':'')+'" data-id="'+i+'"></a>';
}
slider_id.querySelector(".hcg-slider-body").innerHTML = images_div;
slider_id.querySelector(".hcg-slide-dot-control").innerHTML = dots_div;
let slide_index = 0;
let touchStartX = 0;
let touchEndX = 0;
const images = slider_id.querySelectorAll(".hcg-slides");
const dots = slider_id.querySelectorAll(".hcg-slide-dot");
const prev_button = slider_id.querySelector("#hcg-slide-prev");
const next_button = slider_id.querySelector("#hcg-slide-next");
let swipeInProgress = false;
slider_id.addEventListener("touchstart", (event) => {
touchStartX = event.touches[0].clientX;
swipeInProgress = true;
});
slider_id.addEventListener("touchmove", (event) => {
if (swipeInProgress) {
event.preventDefault(); // Prevent scrolling during swipe
}
});
slider_id.addEventListener("touchend", (event) => {
if (swipeInProgress) {
const touchEndX = event.changedTouches[0].clientX;
const swipeDistance = touchEndX - touchStartX;
if (swipeDistance > 0) {
slide_index--; // Swipe to the right, go back one image
} else if (swipeDistance < 0) {
slide_index++; // Swipe to the left, go forward one image
}
showSlides();
updateActiveDot(); // Update the active dot
swipeInProgress = false; // Reset the swipe flag
}
});
const handleSwipe = () => {
const minSwipeDistance = 25; // Adjust the minimum swipe distance as needed
if (touchEndX - touchStartX > minSwipeDistance) {
slide_index--;
} else if (touchStartX - touchEndX > minSwipeDistance) {
slide_index++;
}
showSlides(); // Call showSlides before updating slide_index
// Update the active dot after calling showSlides
dots[slide_index].classList.add("dot-active");
};
const showSlides = () => {
if (slide_index > images.length - 1) {
slide_index = 0;
}
if (slide_index < 0) {
slide_index = images.length - 1;
}
for (let i = 0; i < images.length; i++) {
images[i].style.display = "none";
}
images[slide_index].style.display = "flex";
};
const updateActiveDot = () => {
for (let i = 0; i < dots.length; i++) {
dots[i].classList.remove("dot-active");
}
dots[slide_index].classList.add("dot-active"); // Update the active dot
};
prev_button.addEventListener("click", event => {
event.preventDefault();
slide_index--;
showSlides();
}, false);
next_button.addEventListener("click", event => {
event.preventDefault();
slide_index++;
showSlides();
}, false);
const dot_click = event => {
event.preventDefault();
slide_index = event.target.dataset.id;
showSlides();
}
for (let i = 0; i < dots.length; i++) {
dots[i].addEventListener("click", dot_click, false);
}
})();
</script>