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.

easwee
  • 15,757
  • 24
  • 60
  • 83
emersonthis
  • 32,822
  • 59
  • 210
  • 375

8 Answers8

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://stackoverflow.com/a/16898264/2978727 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();
    }
});
Community
  • 1
  • 1
Michael P
  • 603
  • 1
  • 5
  • 22
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

Community
  • 1
  • 1
Michael P
  • 603
  • 1
  • 5
  • 22
  • 1
    I tried making that switch and it doesn't seem to prevent the bounce. I'm on an iPhone5 with iOS6. – emersonthis Dec 09 '13 at 04:27
  • Thats right. Guess I misunderstood your question. I edited my post to show the full solution. – Michael P Dec 09 '13 at 13:56
  • 1
    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? – emersonthis Dec 09 '13 at 14:00
  • 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. – Michael P Dec 09 '13 at 15:11
  • oh, and '$(document).bind()' is quiet the same in jquery as 'document.addEventListener()' _in this case_ ... – Michael P Dec 09 '13 at 15:15
  • 1
    I tried this, but it did not prevent bouncing on iPhone5s - I did find a way using http://gregsramblings.com/2012/05/23/preventing-vertical-scrolling-bounce-using-javascript-on-ios-devices/ and then adding swipe detect to make a scroll - however the scroll effect was soo poor, so I decided to just live with the bounce – serup Oct 08 '14 at 17:35
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;
}
rbt
  • 115
  • 2
  • 3
  • This stops the bounce effect in Android Chrome too. – ᴇʟᴇvᴀтᴇ Mar 03 '17 at 07:14
  • 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. – Sgnl Jun 27 '17 at 22:49
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>
Lesh_M
  • 596
  • 8
  • 6
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")
  }); 
3

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.

Dr. DS
  • 984
  • 1
  • 13
  • 31
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".

Cesar
  • 420
  • 6
  • 12
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.

C_Sutt
  • 183
  • 1
  • 11