htmlstreamofficial / preline

Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
https://preline.co
Other
4.9k stars 309 forks source link

Carousel slides when swiping vertically #484

Closed damianparrilli closed 2 weeks ago

damianparrilli commented 1 month ago

Summary

I don't know if it's a bug or not but I would like to be able to cancel the vertical swipe for mobile devices. The carousel works in the middle of the page and when trying to scroll the carousel slides

Steps to Reproduce

  1. Go to https://preline.co/docs/carousel.html with a mobile or DevTools in Responsive Design Mode
  2. Try to scroll or swipe down touching any carousel (except those with isSnap)

Demo Link

https://preline.co/docs/carousel.html

Expected Behavior

I want to cancel the vertical swap without having to use isSnap (certain logics used by snap are not efficient for what I need, I'm only having problems with the vertical swipe, everything else works perfectly).

Actual Behavior

What was said in the summary

Screenshots

No response

Root-acess commented 1 month ago

It looks like you're encountering an issue with vertical scrolling on a mobile device where the carousel captures the vertical swipe event, which results in the carousel sliding rather than allowing you to scroll the page. This happens because touch events like swiping are being detected by the carousel, and without special handling, it assumes the user intends to swipe horizontally through the slides instead of scrolling vertically. Solution Overview

To prevent the vertical swipe gesture from being hijacked by the carousel, you can disable the swipe event on the vertical axis and allow the normal scroll behavior to proceed. This can be done by handling touch events and checking if the swipe is mostly vertical. If it is, you prevent the carousel from intercepting the swipe.

Here's a possible approach:

Code to Disable Vertical Swipe for Carousel Listen to touch events: Capture the touch start and touch move events on the carousel. Track the direction of the swipe: Measure the difference between the starting position of the touch and its current position to see if the swipe is more vertical than horizontal. Prevent the swipe: If the swipe is mostly vertical, prevent the default action on the carousel so it doesn't slide.

const carousels = document.querySelectorAll('.carousel-container'); // Select the carousel elements

carousels.forEach(carousel => {
    let startX, startY;

    carousel.addEventListener('touchstart', (e) => {
        startX = e.touches[0].pageX;
        startY = e.touches[0].pageY;
    });

    carousel.addEventListener('touchmove', (e) => {
        const moveX = e.touches[0].pageX;
        const moveY = e.touches[0].pageY;
        const diffX = Math.abs(moveX - startX);
        const diffY = Math.abs(moveY - startY);

        // If the vertical swipe distance is greater than the horizontal swipe distance, prevent the carousel swipe
        if (diffY > diffX) {
            e.stopPropagation(); // Stops the carousel from intercepting the swipe
        }
    });
});

Explanation:

jahaganiev commented 2 weeks ago

Thanks for the input @Root-acess!

@damianparrilli hope that addresses the issue you are facing.