Search code examples
javascripthtmlscrolldom-events

Is it possible to set the context of scroll event to `document.body` instead of `window`?


Backdrop

While I was reading mdn page, I noticed that the left and right sidebars have their scrollbars contained within themselves. But the content area block has its scrollbar in the global context.

demonstration

When I inspected the DOM tree, I saw that the body and html tags doesn't have height property defined on them. So essentially, their were no elements with fixed height (scrollable container) between the content area and the topmost window object. An example of scrollable container

Problem

So this makes window the overflow container for the content area. Further confirming this, I added scroll event listeners to both window and document.body and it turns out that only window event is fired

window.addEventListener("scroll",(e)=>console.log("window scrolling")) 

document.body.addEventListener("scroll",(e)=>console.log("bodyy scrolling"))

But I want the context for scroll should not be window but document.body. And that should fire scroll event from body tag and not window.

What I did

I then added height property to the body tag.

height: 100vh

and then added scroll event listener to it again. But It didn't fired, and I am not able to understand why it didn't?

Adding a height property to a parent which has a value less than its children should make it scrollable right?

I might be missing something fundamental but don't know what? Please help, Thanks!

ref-


Solution

  • Make sure to set the overflow property on the <body>, and on the <html> element to something other than visible because of Overflow Viewport Propagation.

    For a scrollbar to appear, <body>'s height must additionally be less than the content's it contains:

    window.addEventListener("scroll", () => console.log("window scrolled"));
    document.body.addEventListener("scroll", () => console.log("body scrolled"));
    html {overflow-y: hidden}
    body {
      margin: 0;
      height: 100dvh;
      overflow-y: scroll;
    }
    main {
      height: 200%;
      background-color: red;
    }
    <body>
      <main></main>
    </body>