I have an HTML5 app that makes extensive use of its canvas. We started experiencing issues with touch after the iOS 11.3 update.
When implemented, we made sure to explicitly tell the user agent that the event should not be handled. (ie. we added evnt.preventDefault()
We also restricted the canvas, and make sure to disable the browser handling of all panning and zooming gestures. (touch-action: none
, although not Safari does not officially support this basic implementation, this does work on any browser prior iOS 11.3)
This is NOT specific to any browser, but it manifests itself on any iOS device after the 11.3 device.
It can be reproduced using this JSFiddle: https://jsfiddle.net/w542djdw/15/
Any recommendation would be greatly appreciated.
The trick is in how Safari 11.1 (bundled into iOS 11.3) deals with touch events.
From their release notes:
Web APIs:
- Updated root document touch event listeners to use passive mode improving scrolling performance and reducing crashes.
So basically changing this:
// Prevent scrolling when touching the canvas
document.body.addEventListener("touchstart", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
document.body.addEventListener("touchend", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
document.body.addEventListener("touchmove", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
Into this:
// Prevent scrolling when touching the canvas
document.body.addEventListener("touchstart", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, { passive: false });
document.body.addEventListener("touchend", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, { passive: false });
document.body.addEventListener("touchmove", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, { passive: false });
Reading Safari's (iOS 11.3) release notes makes sense after reading the documentation for EventTarget.addEventListener
passive: A Boolean which, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning. See Improving scrolling performance with passive listeners to learn more.
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