Open levymetal opened 6 years ago
Thanks for reporting this bug! Here's the deal:
iOS 11.3 uses passive event listeners by default. Flickity and its dependencies should use { passive: false }
when adding event listeners. (Thx Stack Overflow). This will be coming in the next release.
HOWEVER, iOS 11.3.0 has Bug 184250, which breaks Flickity's behavior of using preventDefault
on touchmove
but not touchstart
. Good news is that this bug has been addressed by WebKit lama Dean Jackson. You can add yourself to the CC list to the WebKit bug to help promote this issue.
For now, my options with iOS 11.3.0 are either prevent all scrolling when you touch inside a Flickity carousel, or keep current behavior, and allow page scrolling to occur with carousel dragging. I choose to keep current behavior.
Add a 👍 reaction to this issue if you ran into this issue as well so I can know how prevalent the issue is. Do not add +1 comments — They will be deleted.
Related: Shopify/draggable#198
I found a workaround for this using the dragStart and dragEnd events:
$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;
}
});
WebKit Bug 184250 has been addressed, received a patch, and is now listed as Resolved. Keep an eye on this bug and future Safari releases to see when this patch lands.
Hello @desandro!
So I'm working on a project where we're using this amazing library, and we were wondering if you've gotten any further insight on this issue about WebKit, their bug page doesn't say too much about the plan on that specific patch.
Thanks!
Sorry, I don't have any insights on updates with this bug at the moment. Anyone with iOS 11.4 installed care to report?
I just upgraded to iOS 11.4.1 and I still have the issue.
Same issue on both iOS Chrome and Safari.
@desandro Is it possible to implement an option so we can choose where to enable / disable the behaviour?
Good news! From Comment 31 on WebKit bug 184250
The fix should be included in the iOS 12 betas.
So when iOS 12 goes out, hopefully this will be resolved.
Just to tell I'm using iOS 12.0 (Beta 8) and still have this issues.
Also seeing the issue in the public release of iOS 12. Just to make sure we are talking about the same issue, here is a video:
https://drive.google.com/file/d/1X6A9Rd9DtAQ6OvkQ-liLcRK8QnSd6PDf/view?usp=sharing
Confirmed. It is not fixed in iOS 12, which really, like, really sucks. Not even the very latest Chrome on iOS12 makes any difference. @desandro Is there nothing we can do?
I solved it by enclosing the carousel in the div id "flick" and added this code:
document.getElementById("flick").addEventListener('touchmove', function(e) { e.preventDefault(); }, { passive: false });
Hi all, Is there an update on this issue? I am still facing the issue on iOS 12
@jatinwaichal which solve have you implemented? Mine works perfectly for me.
@AlexandraKlein Solution worked perfectly fine for me as well. Had to tweak it slightly because I am not using jquery
// this.flkty = new Flickity(element)
this.flkty.on('dragStart', () => (document.ontouchmove = e => e.preventDefault()));
this.flkty.on('dragEnd', () => (document.ontouchmove = () => true));
Ok. So, I'm not crazy? This is good news. : )
I always have such a great experience with Flickity - but in this latest project / I'm definitely feeling whatever this iOS change is.
I was doing some comparisons here: code: https://codepen.io/pxlagency/pen/xmbJyw?editors=0010 And I've added @alexbouchardd 's and @SamHall 's solutions / but I can't tell if it's working as expected. The first one seems to completely disable scrolling in that area / which is rough if you have a slider that takes up most of the screen / and I can't tell if the second one is helping. For viewing on phone: https://s.codepen.io/pxlagency/debug/xmbJyw
In our actual project / we're using vue-flickity / but that wouldn't really change anything - and is why I made this example in a sandbox.
Any ideas?
The dragStart / dragEnd fix doesn't work for me on Safari iOS12. Is there no way around this at all?
any ideas how to fix it?
Btw, a comment in the original IOS bug (Bug 184250), which is now closed, mentions another related IOS bug which has no fix-plans yet: https://bugs.webkit.org/show_bug.cgi?id=185656 and could cause similar problem. So for this reason I hope this bug will receive high priority (the workarounds suggested are also not working for me on IOS 12.1.4)
Any solution how to handle this iOS bug by flickity? Can't you detect the scroll direction and block or allow vertical page scroll?
My 10/23/18 post appears to work. I didn't end up using the page, but it's live and you can see it here: https://chattanoogahistory.com/gallerynew5
@SamHall thank you. Your solution seems to work in your case, but it won't work if you have a fullpage flickity instance (or at least one which takes up most of the viewport). In this case you can't scroll the page because every vertical scroll gets picked up by your implementation. I would need a solution which allows vertical page scroll by detecting the scroll direction(s) and the scroll distance. So, when a users starts scrolling at 200, 100 (x, y) and scrolls to 220, 200 it should assume that the user want's to scroll vertical (so flickity should not grap the scrolling event respectively pass it through). But when the user starts at 200, 100 and scrolls to 280, 90 for example, flickity should grap the event.
Thank you for clarifying ‘vertical page scroll’.
I've got a workaround / temporary fix.
The bug referred to up top (iOS 11.3.0 Bug #184250) is about event.preventDefault()
not working for event listeners registered while inside another event listener. Flickity does just this, adding and removing a touchmove
listener from inside touchstart
/touchend
listeners. It doesn't have to be that way - you could listen to all touchmove
events and not do anything if you don't need to.
Anyways, I don't have the time/desire to refactor Flickity for a workaround, and the maintainers might not want that either. Here's a bit of code that will block vertical scrolling inside .carousel-cell
elements if the swipe is also somewhat horizontal (using Flickity.defaults.dragThreshold
):
https://gist.github.com/woahdae/aa579f1eced44fb89e8fd1b7183d67de
;(function() {
var touchingCarousel = false
, touchStartCoords
document.body.addEventListener('touchstart', function(e) {
if (e.target.closest('.carousel-cell')) {
touchingCarousel = true
} else {
touchingCarousel = false
return
}
touchStartCoords = {
x: e.touches[0].pageX,
y: e.touches[0].pageY
}
})
document.body.addEventListener('touchmove', function(e) {
if (!(touchingCarousel && e.cancelable)) return
var moveVector = {
x: e.touches[0].pageX - touchStartCoords.x,
y: e.touches[0].pageY - touchStartCoords.y
}
if (Math.abs(moveVector.x) > Flickity.defaults.dragThreshold)
e.preventDefault()
}, {passive: false})
// Polyfill for Element.closest
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector
}
if (!Element.prototype.closest) {
Element.prototype.closest =
function(s) {
var el = this
do {
if (el.matches(s)) return el
el = el.parentElement || el.parentNode
} while (el !== null && el.nodeType === 1)
return null
}
}
})();
(the above is written for clarity, not OO best practices etc)
Works perfect for me
var tapArea, startX ;
tapArea = document.querySelectorAll('.gallery');
startX = 0;
for (var item of tapArea) {
item.ontouchstart = function(e) {
startX = e.touches[0].clientX;
};
item.ontouchmove = function(e) {
if (Math.abs(e.touches[0].clientX - startX) > 5 && e.cancelable ) {
e.preventDefault();
}
};
}
@Ross7377 It worked for me too. Thanks for the temporary fix!
Works perfect for me
var tapArea, startX ; tapArea = document.querySelectorAll('.gallery'); startX = 0; for (var item of tapArea) { item.ontouchstart = function(e) { startX = e.touches[0].clientX; }; item.ontouchmove = function(e) { if (Math.abs(e.touches[0].clientX - startX) > 5 && e.cancelable ) { e.preventDefault(); } }; }
@Ross7377 However, for the heads up, this is breaking Flickity on IE11. I had to wrap it in conditional comments:
<!--[if !IE]-->[your script...]<!--<![endif]-->
Yeah, you'd need to use a for loop, or polyfill the for ... of
loop.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
iOS 13 it looks fine here. iOS 12 we also have the problem. We have the solution from @thekevbot included but doesn't work.
adding this css fixes the issue on iOS 13:
.slider {
touch-action: none; -webkit-user-select: none; -webkit-user-drag: none;
}
@saetia yes but with this css you cant scroll Y-axis.
Seems to be an issue on Firefox on Android for me.
@Ross7377, thank you so much for your solution!
@andrey-scada: scrolling issue happened in ios 15, dots also not working
Hi all, if anyone have fixed the iOS 15 issue
Hi all, Is there an update on this scroller issue in iOS 15 I am still facing the issue on iOS 15
@woahdae 's fix is working for me today (may 2022)
I hope someone comes up with a better fix for this issue soon :)
I am wondering if something like this will work?
// stop page from scrolling when swiping flickity
let scrollY;
flkty.on('dragStart', () => {
scrollY = window.scrollY;
});
flkty.on('dragMove', () => {
window.scrollTo(0, scrollY)
});
https://github.com/metafizzy/flickity/issues/457 is back. iOS 11.3 using Safari, Flickity 2.1.1.
Seems to be a problem with iOS 11.3, not a regression in Flickity.
No test case required, the default CodePen demos the issue, as does the Flickity homepage https://codepen.io/desandro/pen/azqbop https://flickity.metafizzy.co