Unable to stop the scrolling of the outer div when end of inner div has reached

1.6k views Asked by At

Use Case : - If the user is scrolling an inner div it should not scroll the outer div once inner div end has reached.

The following code works perfectly fine if the inner div has already reached the end. i.e the touchstart/touchmove event triggers after the inner div has reached the end.

But in case I do not lift the touch and keeps scrolling and if the end of the inner div has reached in this process, it starts scrolling the outer div.

$('body').find('.scrollableDiv').on(
    {
      'touchstart' :  function(e) {
        touchStartEvent = e;
      },
      'touchmove' : function(e) {
        e.stopImmediatePropagation();
        $this = $(this);
        if ((e.originalEvent.touches[0].pageY > touchStartEvent.originalEvent.touches[0].pageY && this.scrollTop == 0) || 
            (e.originalEvent.touches[0].pageY < touchStartEvent.originalEvent.touches[0].pageY && this.scrollTop + this.offsetHeight >= this.scrollHeight)){
          e.preventDefault();
        }
      },  
  }); 

How do I stop scrolling as soon as the end of the inner div is reached? I am trying to achieve this on a browser on android device. Can someone help me in this regard?

NOTE : The user should even be able to scroll the outer div.

Thanks in advance.

2

There are 2 answers

1
Andrew Ice On

If you're using JQuery I would use something that uses scrollTop() to check to see if the user has reached the bottom of the scrollable div and if so, maybe trigger an event that cancels out their scrolling any further? Or something that you may want to do.

Something along the lines of:

$(document).ready(function(){
    $('.scrollableDiv').bind('scroll',scroll_check); 
});

function scroll_check(e){
    var elem = $(e.currentTarget);
    if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()){
      // set overflow-y hidden?
    }
}
0
Barney On

I'm afraid I don't have time to write the explicit code to solve this, but I've got a conceptual solution for you that still might help you.

  1. On DOM ready, wrap each overflow: scroll element with a wrapper with position: relative.
  2. On touch start, for each ancestor with overflow: scroll, set overflow: visible, position: absolute, get calculated height & width and apply these as inline styles, and set top to be the negative of scrollTop — and set the wrapper's overflow to hidden: this means it will be in the same position it was in the first place but unable to move through scrolling.
  3. On touch end, remove the styles applied in step 2.

I can already see caveats:

  1. If you're using relative or absolute positioning for layout within your overflow: scroll elements (and they do not have relative or absolute positioning themselves), this will screw with your layout.
  2. If any scrolling elements are wrapped over after DOM ready, you will need to apply a wrapper for each.

…but it's definitely feasible…