We are trying to scroll an element on our iOS web app while preventing the window itself from scrolling. We are capturing the touchmove
event on the window, scrolling the element programmatically and (trying to) prevent the window itself from scroll by calling preventDefault
on the event.
Unfortunately this doesn't work in Mobile Safari. The window continues to scroll underneath our element. The issue sounds exactly like the Webkit bug described in https://bugs.webkit.org/show_bug.cgi?id=163207, but that issue was supposedly fixed in iOS 10.3 whereas I am running 11.3.
Catching touchforcestart
and calling preventDefault
does seem to prevent scrolling of the window, but we are calling it in touchstart
, which seems to be "too late" since the window still scrolls. Scrolling is only prevented next time touchstart
is called.
Any ideas about what is going on? We are baffled since this is clearly a bug but it seems to have been fixed some time ago.
Go to Settings and tap Accessibility. Turn on the feature, then use the slider to select a sensitivity level.
To make this work we need iOS to think that there is nothing to scroll. But how do we do this? We set the height of both the html and the body element to the window height and then set overflow on these elements to hidden so the content gets cut off.
I recently ran into this same problem. You'll need to pass { passive: false }
when registering the touchmove
event listener. e.g.
document.addEventListener('touchmove', function(e) { e.preventDefault(); }, { passive: false });
This is because document touch event listeners are now passive by default in Safari 11.1, which is bundled with iOS 11.3. This change is documented in the Safari 11.1 release notes:
Web APIs
- [...]
- Updated root document touch event listeners to use passive mode improving scrolling performance and reducing crashes.
You need to bind preventDefault
to two events: touchmove
and touchforcechange
to make it work in ios 11, e.g.
document.addEventListener('touchmove', this.preventDefault, {passive: false}); document.addEventListener('touchforcechange', this.preventDefault, {passive: false});
And you should bind them before touchstart
If you bind them inside your touchstart
or dragStart
handler, they can only prevent scroll in the next dragging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With