Disable IOS Safari Elastic Scrolling

前端 未结 4 2142
心在旅途
心在旅途 2021-02-13 12:32

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 a

相关标签:
4条回答
  • 2021-02-13 12:51

    The above solution 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 wont be. This will actually capture all scroll events even as you scroll to the bottom of the children, so the window's scroll position wont 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.

    0 讨论(0)
  • 2021-02-13 12:51

    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

    0 讨论(0)
  • 2021-02-13 12:57

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

         document.getElementById('content-sections').
             addEventListener('touchmove', function (event) {
                   event.preventDefault();
                   return false;
             });
    
    0 讨论(0)
  • 2021-02-13 13:18

    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.

    0 讨论(0)
提交回复
热议问题