The Document scroll event fires when the document view has been scrolled. Learn how to read window.scrollY, use document.onscroll, throttle handlers the MDN way with setTimeout, and when to prefer IntersectionObserver or scrollend—with five try-it labs.
01
Kind
Document event
02
Type
Event
03
Fires when
Document view scrolls
04
Position
window.scrollY
05
Tip
Throttle heavy work
06
Status
Baseline · Widely available
Fundamentals
Introduction
When the user scrolls the page (or you call APIs that move the document view), the browser fires a scroll event on the Document. That is the signal for sticky headers, progress bars, “back to top” buttons, and parallax-style UI.
Scroll is busy: handlers can run many times per second. MDN warns that expensive DOM work inside every scroll callback can cause jank. Keep the listener light, and throttle work that must update the UI.
💡
Beginner tip
Document scroll is for the page view. If a <div> has its own scrollbar (overflow: auto), listen on that Element instead. To know when scrolling finished, look at scrollend.
Concept
Understanding Document scroll
A standard Document event that answers: “Did the document view just scroll?”
Fires when the document view has been scrolled (MDN).
Event type — a generic Event.
Handler — document.onscroll or addEventListener("scroll", ...).
Position — read window.scrollY / scrollX (or scrollingElement.scrollTop).
MDN’s pattern: update the stored position on every event, but only schedule expensive work if a timer is not already pending. That is real throttling with a measured timeout.
Example 4 — Reading Progress Bar
Map scroll position to a 0–100% progress width (common blog UI).
{ passive: true } tells the browser you will not call preventDefault(), which can help scrolling stay smooth. For heavier paint work, combine this with the throttle pattern from Example 3.
Example 5 — Show “Back to Top” After Scroll
Reveal a button once the user has scrolled past a threshold.
Document scroll is marked Baseline Widely available on MDN (since July 2015). Logos use the shared browser-image-sprite.png sprite from this project. It is a standard Document event used across modern browsers.
✓ Baseline · Widely available
Document scroll
Fires when the document view has been scrolled. Pair with window.scrollY and throttle expensive work.
UniversalWidely available
Google ChromeFull support · Desktop & Mobile
Full support
Mozilla FirefoxFull support · Desktop & Mobile
Full support
Apple SafariFull support · macOS & iOS
Full support
Microsoft EdgeFull support · Chromium & Legacy
Full support
OperaFull support · Modern versions
Full support
Internet ExplorerLong-supported (prefer modern browsers)
Legacy
scrollExcellent
Bottom line: Listen on document for scroll, read window.scrollY, throttle heavy UI updates with setTimeout, and use IntersectionObserver for threshold-based visibility.
Wrap Up
Conclusion
Document scroll is the standard page-scroll signal. Read window.scrollY, keep callbacks cheap, and throttle the MDN way when you must touch the DOM. For finished motion use scrollend; for section visibility prefer IntersectionObserver.
Consider { passive: true } when you never call preventDefault()
Prefer IntersectionObserver for enter-viewport logic
❌ Don’t
Run expensive DOM work on every scroll tick
Assume rAF alone throttles scroll (MDN)
Listen on Document for a nested overflow box
Confuse continuous scroll with finished scrollend
Treat this API as Experimental—it is Baseline
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about Document scroll
Page scrolled — read scrollY and keep handlers light.
5
Core concepts
📄01
View scrolled
document view moved
Event
🔍02
Read Y
window.scrollY
API
⏱️03
Throttle
setTimeout gate
Perf
👁04
Alt
IntersectionObserver
MDN
✅05
Baseline
widely available
Compat
❓ Frequently Asked Questions
It fires when the document view has been scrolled. For element overflow scrolling, use the Element scroll event instead. To detect when scrolling has finished, see Document scrollend.
No. MDN marks Document scroll as Baseline Widely available (since July 2015). It is not Deprecated, Experimental, or Non-standard.
Scroll fires at a high rate. Avoid heavy DOM work on every event. MDN recommends throttling with setTimeout (measuring your own timeout). Using requestAnimationFrame alone to throttle scroll is not useful because it runs at a similar rate.
Commonly use window.scrollY (and window.scrollX). You can also use document.scrollingElement.scrollTop for the scrolling root element.
Yes. You can use document.onscroll or document.addEventListener("scroll", ...).
MDN suggests IntersectionObserver for threshold-based listening (for example, when a section enters the viewport) instead of computing visibility on every scroll event.
Did you know?
MDN explicitly calls out a common mistake: wrapping scroll work in requestAnimationFrame and calling that “throttling.” Because animation frames and scroll events often fire at similar rates, you should measure your own timeout (for example with setTimeout) when you need fewer updates.