ismail9k / vue3-carousel

Vue 3 carousel component
https://ismail9k.github.io/vue3-carousel/
MIT License
660 stars 164 forks source link

How can I prevent scrolling while sliding on mobile? #153

Closed schosdas closed 1 year ago

schosdas commented 2 years ago

Hello I'm a beginner at vue.js.

I want to touch the carousel on the mobile so that the vertical scroll does not work when sliding. (Only horizontal sliding while touching) Does this plug-in include features for this? Thank you.

dixhuit commented 1 year ago

Also looking for this functionality after recent client feedback.

magFixCorp commented 1 year ago

Just use following css .carousel .carouselslide--visible, .carouseltrack, .carousel__viewport { -ms-touch-action: pan-x; touch-action: pan-x; }

ismail9k commented 1 year ago

@magFixCorp Nice workaround!

axelkennedal commented 1 year ago

@magFixCorp this is only a partial solution. Applying pan-x makes it so that the user cannot scroll vertically at all on the carousel. It should still be possible to swipe up and down on the carousel to scroll the entire page up and down.

An idea I had was to apply pan-x when the event slide-start is emit, and then remove that style on slide-end. But when I try to use these events my callback functions are never invoked.

<template>
  ...
  <Carousel @slide-start="handleSlideStart">...
</template>

<script setup>
  const handleSlideStart = () => {
    // this is never called...
    console.log("slide start")
  }
  ...
</script>

I made a separate issue for that here.

I instead tried adapting a solution for another slider component, and it works quite well. The code is in the last few comments here: https://github.com/akiran/react-slick/issues/1240

Here is my adaptation:

<template>
  ...
  <Carousel @touchstart="touchStart" @touchmove="preventVerticalScroll">...
</template>

<script setup>
  let firstClientX;
  const scrollLockThreshold = 100

  const touchStart = e => {
    firstClientX = e.touches[0].clientX
  }

  const preventVerticalScroll = e => {
    const xDiff = Math.abs(e.touches[0].clientX - firstClientX)

    if (xDiff > scrollLockThreshold && e.cancelable) {
      e.preventDefault()
      e.returnValue = false
      return false
    }
  }
  ...
</script>
magFixCorp commented 1 year ago

@axelkennedal this looks like good solution. Maybe we can ask the author @ismail9k to include this piece of code into the carousel itself and make it configurable with a prop

riderx commented 11 months ago

hey @ismail9k i saw you merged a fix, but i still have the issue, should i apply the css solution here to have the fix ?