iOS Safari – How to disable overscroll but allow scrollable divs to scroll normally?

后端 未结 14 1523
南方客
南方客 2020-11-28 17:50

I\'m working on an iPad-based web app, and need to prevent overscrolling so that it seems less like a web page. I\'m currently using this to freeze the viewport and disable

相关标签:
14条回答
  • 2020-11-28 18:00

    Can you just add a little more logic into your overscroll disabling code to make sure the targeted element in question is not one that you would like to scroll? Something like this:

    document.body.addEventListener('touchmove',function(e){
         if(!$(e.target).hasClass("scrollable")) {
           e.preventDefault();
         }
     });
    
    0 讨论(0)
  • 2020-11-28 18:01

    Here's a zepto compatible solution

        if (!$(e.target).hasClass('scrollable') && !$(e.target).closest('.scrollable').length > 0) {
           console.log('prevented scroll');
           e.preventDefault();
           window.scroll(0,0);
           return false;
        }
    
    0 讨论(0)
  • 2020-11-28 18:04

    Using Tyler Dodge's excellent answer kept lagging on my iPad, so I added some throttling code, now it's quite smooth. There is some minimal skipping sometimes while scrolling.

    // Uses document because document will be topmost level in bubbling
    $(document).on('touchmove',function(e){
      e.preventDefault();
    });
    
    var scrolling = false;
    
    // Uses body because jquery on events are called off of the element they are
    // added to, so bubbling would not work if we used document instead.
    $('body').on('touchstart','.scrollable',function(e) {
    
        // Only execute the below code once at a time
        if (!scrolling) {
            scrolling = true;   
            if (e.currentTarget.scrollTop === 0) {
              e.currentTarget.scrollTop = 1;
            } else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
              e.currentTarget.scrollTop -= 1;
            }
            scrolling = false;
        }
    });
    
    // Prevents preventDefault from being called on document if it sees a scrollable div
    $('body').on('touchmove','.scrollable',function(e) {
      e.stopPropagation();
    });
    

    Also, adding the following CSS fixes some rendering glitches (source):

    .scrollable {
        overflow: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
    }
    .scrollable * {
        -webkit-transform: translate3d(0,0,0);
    }
    
    0 讨论(0)
  • 2020-11-28 18:08

    I had surprising luck with with simple:

    body {
        height: 100vh;
    }
    

    It works great to disable overscroll for pop-ups or menus and it doesn't force browser bars to appear like when using position:fixed. BUT - you need to save scroll position before setting fixed height and restore it when hiding the pop-up, otherwise, browser will scroll to top.

    0 讨论(0)
  • 2020-11-28 18:09

    Try this It'll work perfect.

    $('body.overflow-hidden').delegate('#skrollr-body','touchmove',function(e){
        e.preventDefault();
        console.log('Stop skrollrbody');
    }).delegate('.mfp-auto-cursor .mfp-content','touchmove',function(e){
        e.stopPropagation();
        console.log('Scroll scroll');
    });
    
    0 讨论(0)
  • 2020-11-28 18:11

    Best solution to this is css/html: Make a div to wrap your elements in, if you dont have it already And set it to position fixed and overflow hidden. Optional, set height and width to 100% if you want it to fill the whole screen and nothing but the whole screen

    #wrapper{
      height: 100%;
      width: 100%;
      position: fixed;
      overflow: hidden;
    }
    <div id="wrapper">
      <p>All</p>
      <p>Your</p>
      <p>Elements</p>
    </div>

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