metafizzy / flickity

:leaves: Touch, responsive, flickable carousels
https://flickity.metafizzy.co
7.53k stars 602 forks source link

Disable vertical page scrolling when dragging on mobile #1196

Open desandro opened 2 years ago

desandro commented 2 years ago

v2.3.0 resolved some iOS 15 issues #1177, but the page continues to scroll vertically when dragging horizontally.

wplit commented 2 years ago

Just leaving a link here to a comment that has a code solution that seems to solve this when I'm testing on iOS15..

https://github.com/metafizzy/flickity/issues/1177#issuecomment-979352698

Denoy158 commented 2 years ago

Just leaving a link here to a comment that has a code solution that seems to solve this when I'm testing on iOS15..

#1177 (comment)

In my case, this solution break flickity 2.3.0 (I can't scroll horizontally and change slides at all), but works on previous version.

This works for me on flickity 2.3.0

$carousel.on( 'dragStart.flickity', function( event, pointer ) {
    document.ontouchmove = function (e) {
        e.preventDefault();
    }
});

$carousel.on( 'dragEnd.flickity', function( event, pointer ) {
    document.ontouchmove = function (e) {
        return true;
    }
});

Would be great to have official fix to be honest

CorySchulz commented 2 years ago

Did we ever find a good fix for this? I'm still seeing vertical scrolling on 3.0.0 when trying to swipe through the slides.

kevin-johne commented 2 years ago

I tried earlier solutions from #1777 but their are making the slider not useable on iOS. The only thing which worked for me was to use the hack which is used usually when opening modals and you don't want the page to scroll. This needs some more testing an refinement, however this could be an approach for some of us. So setting the html to height 100% and overflow hidden, so that there is actually no vertical scroll. I know that this will not work for all applications as it might interfere with other styles.

class PatchedFlickity extends Flickity {
  constructor (...args) {
    super(...args);

    this.html = document.querySelector('html');
    this.ignoringVerticalScroll = navigator.userAgent.match(/mobile/i) && navigator.userAgent.match(/safari/i);

    if(this.ignoringVerticalScroll) {
      this.on('dragStart', (event, pointer) => {
        let moveVector = {
          x: pointer.pageX - this.pointerDownPointer.pageX,
          y: pointer.pageY - this.pointerDownPointer.pageY,
        };
        if(Math.abs(moveVector.x) > Math.abs(moveVector.y)) {
          this.freezeVerticalScroll();
        }
      });

      this.on('dragEnd', () => {
        this.unfreezeVerticalScroll();
      })
    }
  }

  freezeVerticalScroll () {
    this.htmlDefaultOverflow = this.html.style.overflow;
    this.htmlDefaultHeight = this.html.style.height;
    this.html.style.overflow = "hidden";
    this.html.style.height = "100%";
  }

  unfreezeVerticalScroll () {
    this.html.style.overflow = this.htmlDefaultOverflow;
    this.html.style.height = this.htmlDefaultHeight;
  }
}
CorySchulz commented 2 years ago

We couldn't get a solution to work in a reliable way so unfortunately we ended up having to recode all of the sliders at my job in Slick. This bug is a huge deal breaker for me moving forward, probably not using Flickity for anything anymore.

desandro commented 1 year ago

Possible solution https://wpdevdesign.com/fixing-flickitys-issue-with-ios15-safari/

AndreFCAmorim commented 1 year ago

I manage to fix this issue with the following CSS code: Check if also work with you guys.

.flickity-enabled {
    -webkit-overflow-scrolling: touch;
    overflow: hidden;
}

.flickity-viewport {
    height: 100%;
    overflow: hidden;
    position: relative;
    touch-action: pan-y;
    -webkit-transform: translate3d(0, 0, 0);
}

.flickity-slider {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
}

.flickity-enabled.is-draggable .flickity-viewport {
    overflow-y: hidden;
    overflow-x: scroll;
}

.flickity-enabled.is-draggable .flickity-viewport::-webkit-scrollbar {
    height: 0;
    width: 0;
    display: none;
}