iOS: disable bounce scroll but allow normal scrolling
Asked Answered
S

8

28

I don't want the content of my site sloshing around when the user hits the edge of a page. I just want it to stop.

The omni-present javascript solution I see everywhere is this:

$(document).bind(
   'touchmove',
   function(e) {
     e.preventDefault();
   }
);

But this prevents scrolling entirely. Is there way to just remove the bounce. Preferably with CSS or a meta tag as opposed JS, but anything that works will do.

Smashing answered 9/12, 2013 at 1:15 Comment(0)
S
21

I have to add another answer. My first approach should work, but, there is an iOS bug, which still bumbs the whole page, even if e.stopPropagation.

mikeyUX find a workaround for this: https://mcmap.net/q/160461/-document-ontouchmove-and-scrolling-on-ios-5 I wonder why he just get a few clicks for this great idea...

This is how I used his approach in my case:

var content = document.getElementById('scrollDiv');
content.addEventListener('touchstart', function(event) {
    this.allowUp = (this.scrollTop > 0);
    this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight);
    this.slideBeginY = event.pageY;
});

content.addEventListener('touchmove', function(event) {
    var up = (event.pageY > this.slideBeginY);
    var down = (event.pageY < this.slideBeginY);
    this.slideBeginY = event.pageY;
    if ((up && this.allowUp) || (down && this.allowDown)) {
        event.stopPropagation();
    }
    else {
        event.preventDefault();
    }
});
Selda answered 9/12, 2013 at 17:40 Comment(2)
still not satisfied with the answer ?Selda
Missing ) on the last line ;) Also, didn't work for me , as my element is only visible when you click the modal - damn iOS :(Thebaine
S
12

Disable bouncing by prevent the default behaviour of the document:

document.addEventListener("touchmove", function(event){
    event.preventDefault();
});

Allow scrolling by prevent that the touch reaches the document level (where you would prevent the scrolling):

var scrollingDiv = document.getElementById('scrollDiv');
scrollingDiv.addEventListener('touchmove', function(event){
    event.stopPropagation();
});

Mind the difference between these two:

event.stopPropagation()
event.preventDefault()

StopPropagation should be your choice here ! Here is a very good explanation: http://davidwalsh.name/javascript-events

Edit: Same problem, same solution: document.ontouchmove and scrolling on iOS 5

Edit2: fixed typo in variable names added brackets after methods

Selda answered 9/12, 2013 at 3:41 Comment(6)
I tried making that switch and it doesn't seem to prevent the bounce. I'm on an iPhone5 with iOS6.Smashing
Thats right. Guess I misunderstood your question. I edited my post to show the full solution.Selda
I don't know much about event propagation in iOS, so it's not obvious to me what the final code should be from your answer. Do you mind clarifying what the final code snippet should look like to accomplish what I'm trying to do?Smashing
There is nothing more. Replace 'scrollDiv' with your div-ID you want to be able to scroll and call the lines in the first two boxes above in a '$(document).ready' function, or whereever you want after the site has been loaded.Selda
oh, and '$(document).bind()' is quiet the same in jquery as 'document.addEventListener()' in this case ...Selda
I tried this, but it did not prevent bouncing on iPhone5s - I did find a way using gregsramblings.com/2012/05/23/… and then adding swipe detect to make a scroll - however the scroll effect was soo poor, so I decided to just live with the bounceMolten
B
8

If apply to Desktop Browser, don't need any JavaScript codes, just few lines of CSS codes:

html {
    height  : 100%;
    overflow: hidden;
}
body {
    height  : 100%;
    overflow: auto;
}
Beauvoir answered 11/3, 2015 at 11:34 Comment(2)
This stops the bounce effect in Android Chrome too.Jezabel
This stops the bounce effect on my iOS Chrome browser but I lose the smooth scrolling "flick" effect. The scrolling becomes quite choppy and doesn't decelerate towards a stop.Undercool
D
6

iOS 16 started support of css overscroll-behavior. If you are targeting > iOS 16 devices (including its WKWebview), to prevent overscroll bounce, the solution is simple

add following CSS

html {
  overscroll-behavior: none;
}

Tested in iOS 16 and above.

Deadfall answered 14/1, 2023 at 17:28 Comment(1)
Working also in iOS PWA applicationSleepy
O
5

I tried lots of different approaches I found here on stackoverflow, but iNoBounce was the thing that really worked for me: https://github.com/lazd/iNoBounce

I just included it in my index.html:

<script src="inobounce.js"></script>
Oxy answered 31/12, 2015 at 11:6 Comment(4)
But there ins't anything else to do.. :| It solved the question's problem which was exactly like mine.Oxy
If that is the case then you are all set. I did not downvote or flag it.Introversion
It's not removing completely the bounce effect but it's doing really good job :)Nostoc
I did this to make it work properly I applied it to a wrapper div which has all the content inManet
E
3

This library is solution for my scenarios. Easy way to use just include library and initialize where you want like these;

noBounce.init({   
    animate: true
});

If you want to prevent bouncing only on one element and not on the whole page you can do it like:

 noBounce.init({
    animate: true,
    element: document.getElementById("content")
  }); 
Ethridge answered 23/3, 2016 at 8:26 Comment(1)
This disables all scrolling... so kind of useless? but maybe I didn't use it right...Acierate
R
0

Found a code that worked to me, I believe it will work to you.

The solution is written here: http://apdevblog.com/optimizing-webkit-overflow-scrolling/

Basically, you need to have this js code:

    document.addEventListener("DOMContentLoaded", ready, false);
    document.addEventListener("touchmove", function (evt)
    {
        evt.preventDefault();
    }, false);

    function ready()
    {
        var container = document.getElementsByClassName("scrollable")[0];
        var subcontainer = container.children[0];
        var subsubcontainer = container.children[0].children[0];

        container.addEventListener("touchmove", function (evt)
        {
            if (subsubcontainer.getBoundingClientRect().height > subcontainer.getBoundingClientRect().height)
            {
                evt.stopPropagation();
            }
        }, false);
    }

And then, have your scrollable divs with the class="scrollable".

Radiculitis answered 14/2, 2014 at 18:15 Comment(0)
P
0

After trying these suggestions and reading several articles, the fix for me was to use the CSS property < overflow-x: hidden; > on the problematic element/container.

Pyx answered 30/5, 2019 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.