EDIT FOR CLARIFICATION:
What I want:
- I should be able to swipe my finger around without the webpage trying to scroll
- I should be able to swipe my finger around without the contents of the webpage being nudged in any way (normally, when one scrolls to the end of a scroll region, the browser allows some additional spring-loaded buffer scrolling to signal to the user that it is the end of the scroll region).
- I should be able to pinch and pan without the webpage zooming
I need to interpret these events accurately and in realtime MYSELF to respond to these actions WITHIN THE CANVAS. (I am doing realtime drawing via
requestAnimationFrame, allowing me to react to user events without using the DOM)
The state of things currently:
This all works perfectly (except for the ability to open a new window) because I position the canvas to be the full size of the viewport (handling any window resize events), and the canvas listens to
ontouchend, etc… events, calling
evt.preventDefault() after I have handled the user input myself. This works to ensure the canvas is ALWAYS full screen, doesn’t budge, and user input is accurately given to me to handle in-game.
One bit of user input I need to handle is the launching of a webpage when they click the region of my canvas with a “launch my webpage” button. However,
window.open(mywebpage) doesn’t work, because mobile safari only allows such an action in the callstack of a
click event. Because I rely on
ontouchstart to get responsive controls, and
evt.preventDefault() in an
ontouchstart event CANCELS the
click event from happening, I cannot launch the webpage (it gets blocked by the browser).
My attempted solutions, and why they are insufficient:
- Just use a click event rather than ontouchstart: this means I can’t prevent scrolling/etc… additionally, it is not as responsive, and doesn’t allow me to handle touch-and-drag events well.
- Overlay a
div (or an
a) tag atop the canvas over the launch webpage zone, and add a click event to that: if the user clicks-and-drags starting within this tag, then it allows the page to scroll and zoom. Trying to fix this results in the same problem as before.
I have a mobile application that is a full-screen canvas, which locks itself positionally (can’t scroll or zoom) so that I can correctly interpret user input uninterrupted (swipes, pans, etc…).
It locks itself in by intercepting
touchstart events and calling
evt.preventDefault (as well as the meta viewport no-zoom stuff which as far as I can tell doesn’t actually do anything?).
This works great, and is absolutely necessary to make a game (or game-like application) function.
The problem is that I also have a “go to this webpage” button. I can intercept the
touchstart, and use
window.open(somewebpage), but mobile popup blockers will block it. The “rules” seem to be “the webpage will be allowed to be opened iff it is done in the call stack of a user interaction, AND that interaction is a ‘click’ event”.
I have the first part down, but if I change the event to a
click event, the web page now interprets swipes as scrolls (and pinches as zooms, etc…). If I have both a
click and a
touchstart event, then calling
evt.preventDefault() on the
touchstart (which stops the scroll/zoom) also stops the
If I overlay a
div atop the click zone of the “launch webpage” button, then the player can scroll/zoom when their input begins in that button, which results in an unpredictable and wonky experience.
How can I launch another webpage without allowing the current webpage to scroll?
Edit: at request, here is a code snippet at least partially illustrating what I’m trying to do https://jsfiddle.net/phildo/0q8e47fk/10/.
Note that in the “real” case, the canvas takes up the full width/height of the screen, and is explicitly set accordingly on screen resize.
Preventing bounces of any kind on mobile web page is a vast problem through out the mobile devices not depending about the manufacturer. I had similar issue on Windows Phone 8 app years ago and there (quite surprisingly) was a solution dedicated to Windows environment which of course cannot applied here.
For iOS you need an iOS solution, right?
The very solution is named
iNoBounce. The idea is to add the little
js library to your html page, code with some good conventions and the
js lib will do the dirty job of preventing the default when necessary.
The trick it actually does is not to prevent just anything, but the ones only, that are “extra” and will cause the bounce events.
With the words of
iNoBounce GitHub Readme:
iNoBounce detects if the browser supports
-webkit-overflow-scrolling by checking for the property on a fresh
CSSStyleDeclaration. If it does,
iNoBounce will listen to
touchmove and selectively
move events that don’t occur on a child of an element with
-webkit-overflow-scrolling: touch set. In addition,
preventDefault() when the user is attemping to scroll past the bounds of a
scrollable element, preventing rubberbanding on the element itself (an unavoidable caveat).
The example code asks you to use the following parts (there is a separate example code for canvas, this is only the most common solution):
// All you need is an element with `height` or `max-height`, `overflow: auto` and `-webkit-overflow-scrolling: touch`.
border: 1px solid gray;
I found out you did not limit yourself to iOS. For other browsers, try
overscroll-behavior setting, that you can set to
none to disable bounces.
It will work only on Android, not ie or iOS.
For mobile Windows Phone I had the solution like this:
which effectively does the same as iNoBounce, now with single CSS line for the div containing the canvas.
For a search of semi universal solution, I could find that
applied to div element that includes the canvas, you can disable default touch events and for the canvas, define your own.
The solution works on any other than Safari browsers. As in  there may be some variants like
but I suppose they are now all same without prefixes. The  solution is very old and world has changed a lot from those days.
The sad thing is, the browser support is same at least 2019  and maybe now also.
 jQuery / HTML5 / gwt app for WP8 (Lumia 920) device: vertical css scroll fix