Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums CSS Prevent body scrolling when the user scrolls on fixed position div

  • This topic is empty.
Viewing 6 posts - 31 through 36 (of 36 total)
  • Author
    Posts
  • #254346
    Shikkediel
    Participant

    Glad to see it could help you out. :-)

    #265961
    leocavalcante
    Participant

    $('#fixed').bind('mousewheel DOMMouseScroll', function(e) { var scrollTo = null; if (e.type == 'mousewheel') { scrollTo = (e.originalEvent.wheelDelta * -1); } else if (e.type == 'DOMMouseScroll') { scrollTo = 40 * e.originalEvent.detail; } if (scrollTo) { e.preventDefault(); $(this).scrollTop(scrollTo + $(this).scrollTop()); } });
    #265976
    Shikkediel
    Participant

    That’s not gonna do much on a mobile device (nor does it seem very relevant to the initial question)…

    #266076
    stenvinj
    Participant

    I have also faced the same. Now its fixed. Thanks.

    #266424
    schkolne
    Participant

    Hey this has been a very helpful thread thanks everyone! I have been working on a scrollable overlay that shows in iOS on top of a regular page. I managed to get the scroll to work for the overlay well, turning off the scroll for the underlying page, using overflow-y technique. However I ran into a strange glitch.

    It is related to this problem — http://blog.christoffer.online/2015-06-10-six-things-i-learnt-about-ios-rubberband-overflow-scrolling/ — but slightly different and I did a slightly different fix.

    My issue in particular was that, when I scrolled down to the bottom of my overlay, it would rubber band just fine. But after it rubber-banded and came to rest, if i tried scrolling it again, the overlay would NOT rubber-band as one would expect. Instead the underlying content scrolled while the overlay remained frozen in place. This would happen for a while, usually until the underlying content rubber-banded on the other side of the screen. At which point, suddenly my overlay would start scrolling again.

    I debugged this pretty heavily but couldn’t make sense of it. It seemed to be related to a weird resize event, but that wasn’t consistent. I tried to stop the event from propagating to the underlying body, but that somehow didn’t stop the underlying body from scrolling. It was as if the overlay was processing a scroll, but visually it wasn’t moving instead the other stuff was.

    Anyway I did come up with a fix. My basic solution was to trap and ignore the user trying to rubberband the detail in this way. Instead, I just cancelled the events. This gave me most of the goodness of iPhone style momentum scrolling, with none of the weird buggy stuff.

    well I had this detailManager thing which i used to hold a variable

    var $detailManager = {
      // used for iOS touchstart/touchmove issue fix
      touchStartY        : 0,
    

    when the overlay detail is shown, i add some events to explictly catch when the user is trying to rubberband the detail overlay in either direction, and event.preventDefault() to cancel. The below code is in my showDetail() handler:

        $detail.bind('touchstart', function(event) {
          $detailManager.touchStartY = event.originalEvent.touches[0].clientY;
        });
    
        $detail.bind('touchmove', function(event) {
          var touchY = event.originalEvent.changedTouches[0].clientY;
    
          var scrollTop = $(this).scrollTop();
          var totalScroll = $(this).prop('scrollHeight');
          var currentScroll = scrollTop + $(this).outerHeight();
    
          // at we're at the top of page, and moving down, disable this event
          if (scrollTop === 0 && touchY > $detailManager.touchStartY) {
            event.preventDefault();
          }
          // similarly disable if we're at the bottom of the page, and moving up
          else if (currentScroll === totalScroll && touchY < $detailManager.touchStartY) {
            event.preventDefault();
          }
        });
    

    and for good measure, I put the below in my hideDetail() handler:

            // remove these event handlers for good measure
            // we don't want to add multiple handlers if we click this again
            $detail.unbind('touchstart');
            $detail.unbind('touchmove');
    

    I spent way too much of my life on this bug, I hope this helps someone else out.

    #266962
    willmcpo
    Participant

    I wrote an npm package (body-scroll-lock) to solve this problem for all devices including iOS. Basically, it locks body scroll without locking the scrolling of a target element. It uses CSS for non iOS devices, and JS for iOS devices. It also avoids the troubles of using a position: fixed container. Works on desktop browsers too.

    https://www.npmjs.com/package/body-scroll-lock

    Here’s a demo

    For more details on the rationale of this package, check out: https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177.

    Give the package a try – if it works for you, please star the Github repo =)

Viewing 6 posts - 31 through 36 (of 36 total)
  • The forum ‘CSS’ is closed to new topics and replies.