admin管理员组

文章数量:1181449

I am writing a web app in HTML and JavaScript for use on an iPhone. What I would like to achieve is preventing the app from elastic scrolling (scrolling past the pages extents and bouncing back). However, I need some of the longer elements of my app to be able to be scrolled (the app has a long canvas).

I have tried many answers to this found elsewhere on the internet, however, all of those solutions either used JQuery, disabled scrolling altogether, used Phonegap or just plain didn't work on IOS 7. How can I do this?

I am writing a web app in HTML and JavaScript for use on an iPhone. What I would like to achieve is preventing the app from elastic scrolling (scrolling past the pages extents and bouncing back). However, I need some of the longer elements of my app to be able to be scrolled (the app has a long canvas).

I have tried many answers to this found elsewhere on the internet, however, all of those solutions either used JQuery, disabled scrolling altogether, used Phonegap or just plain didn't work on IOS 7. How can I do this?

Share Improve this question edited Jun 16, 2014 at 2:03 Phedg1 asked May 26, 2014 at 3:16 Phedg1Phedg1 1,9683 gold badges18 silver badges38 bronze badges 3
  • 1 see this answer stackoverflow.com/a/16898264/112731 – Onur Yıldırım Commented Jun 7, 2014 at 1:19
  • 2 possible duplicate of How to disable rubber band in iOS web apps? – mplewis Commented Jun 16, 2014 at 2:28
  • 1 The solution given on that question no longer works. You experience jittering at the upper and lower limits. – Phedg1 Commented Jun 18, 2014 at 4:18
Add a comment  | 

4 Answers 4

Reset to default 22 +25

There is a way to achieve this without jQuery:

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

But this is not a proper solution. It's better to wrap your content in some div, and use css property on it:

 -webkit-overflow-scrolling: touch;

Here is the example

Edit:

This will only prevent overscroll in webview, not in app. So you need to disable this feature in app config. If you use phonegap:

<preference name="DisallowOverscroll" value="true" />

More description here

If you don't use phonegap, you can use this.

So when you have scroll content in body & want to disable elastic scroll use:

let scrollToTop = $(window).scrollTop();
if (scrollToTop < 0) {
   // do something here
}

Because elastic scroll will always have negative value

One of the other solutions here was insufficient in my case. It prohibits all scrolling. It is possible to build a solution here that prevents elastic scrolling in iOS, but that still allows scrolling on children. I this took the above solution and added a check that bubbles up the DOM to determine which scrollable element "owns" the scroll event, and if it's the root element of the page, I drop it:

function overflowIsHidden(node) {
  var style = getComputedStyle(node);
  return style.overflow === 'hidden' || style.overflowX === 'hidden' || style.overflowY === 'hidden';
}

function findNearestScrollableParent(firstNode) {
  var node = firstNode;
  var scrollable = null;
  while(!scrollable && node) {
    if (node.scrollWidth > node.clientWidth || node.scrollHeight > node.clientHeight) {
      if (!overflowIsHidden(node)) {
        scrollable = node;
      }
    }
    node = node.parentNode;
  }
  return scrollable;
}

document.addEventListener('DOMContentLoaded', function() {

    document.body.addEventListener('touchmove', function(event) {
      var owner = findNearestScrollableParent(event.target);
      if (!owner || owner === document.documentElement || owner === document.body) {
        event.preventDefault();
      }
    });

}, false);

At this point, the body is no longer scrollable or elastically scrollable in iOS, but children elements are. You can then add -webkit-overflow-scrolling: touch; to those children so they are elastic but the document won't be. This will actually capture all scroll events even as you scroll to the bottom of the children, so the window's scroll position won't ever change erroneously. Alternatively you may also consider:

['resize', 'orientationchange', 'scroll'].forEach(function(event) {
  window.addEventListener(event, function() {
    window.scrollTo(0, 0);
  });
});

which in addition to the first code block I shared, should really throw an axe at document scrolling in iOS altogether.

Based on answer by @umidbek this is how it worked for me

     document.getElementById('content-sections').
         addEventListener('touchmove', function (event) {
               event.preventDefault();
               return false;
         });

本文标签: javascriptDisable IOS Safari Elastic ScrollingStack Overflow