.scroll() is jQuery’s legacy shorthand (since 1.0) for binding or triggering the browser scroll event on window or a scrollable element. It is deprecated since 3.3 but still works in jQuery 3.x. Prefer .on("scroll") / .trigger("scroll").
Remember
// Deprecated (since 3.3) — still works in jQuery 3.x
$("#target").scroll(function () {
// scroll position changed
});
$("#target").scroll(); // trigger
// Modern replacements
$("#target").on("scroll", handler);
$("#target").trigger("scroll");
Rename. Migration is a straight API change for simple bindings.
Cleanup. Pair modern binds with .off("scroll", fn).
Example 5 — Throttle Inside .scroll()
Legacy bind, modern habit: run heavy work at most every 150 ms while scrolling.
jQuery
var raw = 0, th = 0, last = 0;
$("#target").scroll(function () {
raw++;
$("#raw").text(raw);
var now = Date.now();
if (now - last >= 150) {
last = now;
th++;
$("#th").text(th);
}
});
Fast scroll →
Raw count climbs quickly
Throttled count grows slower (~every 150ms)
How It Works
Count raw. Every scroll event increments raw.
Gate. Expensive work runs only if 150 ms have passed.
Compare. Throttled runs stay far below raw event count.
Same rule. Throttle applies whether you use .scroll() or .on().
Edge Cases & Pitfalls
Watch for these when reading or migrating legacy scroll code.
deprecated
Do not use in new code
.scroll(handler) is deprecated since 3.3. Prefer .on("scroll").
vs
Not the same as .scrollTop()
.scroll() binds/triggers an event. .scrollTop() gets or sets position.
target
Bind the element that scrolls
Page scroll → window. Panel scroll → that overflow element. Wrong target means silence.
removed?
Not removed like .error()
.scroll() still exists in jQuery 3.x. .error() was removed in 3.0 — do not treat them the same.
Compatibility
Browser Support
The .scroll() method has been part of jQuery since 1.0. Binding via .scroll(handler) is deprecated since 3.3 but still functional in jQuery 3.x. Prefer .on("scroll") / .trigger("scroll").
✓ Deprecated · jQuery 1.0+
jQuery .scroll()
Works wherever your loaded jQuery version runs. Prefer .on('scroll') for new projects. Applies to window and scrollable overflow elements.
100%With jQuery 3.x
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
.scroll()Legacy API
Bottom line: Safe in legacy jQuery projects. Migrate bindings to .on('scroll') and triggers to .trigger('scroll') when updating code.
Analysis
Performance Notes
Approach
Cost
Best for
Light log / scrollTop read
Cheap
Debugging, simple labels
Throttled progress / sticky check
Cheap–moderate
Live UI while scrolling
Heavy DOM work every scroll
Expensive
Avoid — throttle or debounce
Legacy and modern binds have the same cost. Keep handlers light, and throttle anything that measures or redraws the DOM.
Remember
Key Takeaways
Role: legacy bind/trigger for the scroll event.
Migrate:.on("scroll", fn) — preferred since 3.3.
Trigger: use .trigger("scroll") instead of no-arg .scroll().
Throttle: expensive work should not run on every raw event.
One line:.scroll() is deprecated sugar for .on("scroll") / .trigger("scroll").
Frequently Asked Questions
The .scroll() method has two roles. With a handler — .scroll(handler) or .scroll(eventData, handler) — it binds a function that runs when the user scrolls a matched element. Bind on $(window) for page scroll or on an overflow element for container scroll. With no arguments — .scroll() — it triggers the scroll event. Both forms exist since jQuery 1.0; binding is deprecated since 3.3.
Deprecated, not removed. Binding signatures are deprecated since jQuery 3.3 — use .on("scroll", handler) instead. Unlike .error(), which was removed in jQuery 3.0, .scroll() still works in jQuery 3.x. Prefer .trigger("scroll") over no-arg .scroll() for clarity.
.scroll(handler) registers a callback and does not fire immediately. .scroll() with no arguments triggers the scroll event on each matched element — the same as .trigger("scroll"). Bind on the element whose scrollTop or scrollLeft actually changes.
.scroll() is an event shorthand — it binds or triggers the scroll event. .scrollTop() gets or sets the vertical scroll position. They are not interchangeable: binding .scroll() does not move the page, and .scrollTop(100) does not register a listener.
Replace .scroll(fn) with .on("scroll", fn). Replace .scroll(data, fn) with .on("scroll", data, fn). Replace no-arg .scroll() with .trigger("scroll"). Cleanup with .off("scroll"). Under the hood, .scroll(handler) already delegates to .on("scroll").
Yes. Scroll can fire dozens of times per second. Wrap progress bars and sticky checks in throttle (or debounce when you only need the final position), whether you use legacy .scroll(fn) or modern .on("scroll", fn).