Search code examples
javascriptjqueryhtmleventsscroll

prevent Scroll bubbling from element to window


I have a modal box window (pop-up) that contains an iframe,
and inside that iframe there's a div that is scrollable.

When I scroll the iframe's inner DIV, and it has reached its top or bottom limit,
the window of the browser itself starts to scroll. this is an unwanted behavior.

I've tried something like this, which kills the main window scroll when
onMouseEnter when mouse enters pop-up box area:

e.preventDefault() is not working as it should for some reason...

$("#popup").mouseenter(function(){
   $(window).bind("scroll", function(e){
        e.preventDefault();
   }); 
}).mouseleave(function(){
    $(window).unbind("scroll");
});

Solution

  • Solved (for some browsers) using a simple CSS property:
    overscroll-behavior:

    auto The default scroll overflow behavior occurs as normal.

    contain Default scroll overflow behavior is observed inside the element this value is set on (e.g. "bounce" effects or refreshes), but no scroll chaining occurs to neighboring scrolling areas, e.g. underlying elements will not scroll.

    none No scroll chaining occurs to neighboring scrolling areas, and default scroll overflow behavior is prevented.

    body{
      height: 600px;
      overflow: auto;
    }
    
    section{
      width: 50%;
      height: 50%;
      overflow: auto;
      background: lightblue;
      overscroll-behavior: none; /*   <--- the trick    */
    }
    
    section::before{
      content: '';
      height: 200%;
      display: block;
    }
    <section>
     <input value='end' />
    </section>

    Simply apply that style property on the element which the scroll should be "locked-in" to and the scroll event will not bubble up to any parent element which might have a scroll as well.


    Same demo as above but without the trick:

    body{
      height: 600px;
      overflow: auto;
    }
    
    section{
      width: 50%;
      height: 50%;
      overflow: auto;
      background: lightblue;
    }
    
    section::before{
      content: '';
      height: 200%;
      display: block;
    }
    <section>
     <input value='end' />
    </section>