glidejs / glide

A dependency-free JavaScript ES6 slider and carousel. It’s lightweight, flexible and fast. Designed to slide. No less, no more
https://glidejs.com
MIT License
7.34k stars 770 forks source link

Swiping horizontally on iOS webkit page is moving vertically #399

Open karolisgrinkevicius-home24 opened 5 years ago

karolisgrinkevicius-home24 commented 5 years ago

Description

πŸ’© Current behaviour

Swiping the slider horizontally the whole page is moving vertically using iOS webkit based browser. I have recorded the screen using iOS 12.3.1 Safari (but the same behaviour is happening on every iOS webkit based browser). IMG_0462 TRIM

🀘🏻 Expected behaviour

The whole page doesn't move vertically while swiping horizontally on the Glide slider container target.

Notes

I.e. slick carousel library has this issue solved.

Dependencies and their versions

└── @glidejs/glide@3.3.0
Livog commented 5 years ago

This took me some time todo. But I have a solution and maybe it will give a hint of what needs to be done. This probably should not be the end solution since maybe it's not so performance-optimized or clean. But it works.

I would guess that Glide checks what angle we are dragging to and if the angle is within the range that we want, it should do e.preventDefault(); to stop the browser from scrolling. I find this being the best way since messing with overflow: hidden; or body { position: fixed } usually just mess up things.

This solution is not perfect, it has the same flaws that slick slider do. Dragging horizontally down will move both slider and body.

Code:

import _throttle from 'lodash/throttle'; //Using lodash/throttle to throttle the call
let swipeStartX = 0,
    swipeStartY = 0,
    slider = document. getElementById('slider');
slider.addEventListener('touchstart', _throttle((e) => {
  swipeStartX = e.pageX; //
  swipeStartY = e.pageY;
}));
let allowAngle = 45;
slider.addEventListener('touchmove', _throttle((e) => {
  var angle = Math.atan2(e.pageY - this.swipeStartY, e.pageX - this.swipeStartX) * 180 / Math.PI
  var isHorizontalScrolling = angle <= allowAngle && angle >= -allowAngle || (angle <= 180 && angle >= (180 - allowAngle) || angle >= -180 && angle <= (-(180) + allowAngle)); // This line could be a bit overcomplicated

  if(!isHorizontalScrolling){
    return true;
  } else {
    e.preventDefault();
  }
}, { passive: false }), 2);

If someone has better ways to do this, please let us know.

Hopefully, a fix for this bug could be implemented into the core of Glide.

dskoziol commented 5 years ago

This is also related to issues #207 and #258. On my side I can confirm that is not a problem in Chrome on Android, but is a problem with Chrome and Safari in iOS.

olgagiza-home24 commented 5 years ago

I created PR for this case: https://github.com/glidejs/glide/pull/406 πŸ˜ƒ