jQuery .scroll() Method

Beginner
7 min read
Updated: Oct 2026
5 examples
Live preview

What Is .scroll()?

.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");
NeedUse
New code (bind)$("#el").on("scroll", fn)
New code (trigger)$("#el").trigger("scroll")
Legacy bind$("#el").scroll(fn) ⚠
Legacy trigger$("#el").scroll() ⚠
Position (not an event)$("#el").scrollTop()
Remove handler$("#el").off("scroll", fn)

How to Use .scroll()

Recognize the legacy call, bind the element that scrolls, and migrate to .on() / .trigger().

  1. Bind with $("#el").scroll(handler) (legacy) or .on("scroll", handler) (preferred).
  2. Optionally pass eventData: .scroll(data, handler) → .on("scroll", data, handler).
  3. Trigger with no-arg .scroll() (legacy) or .trigger("scroll") (preferred).
  4. Throttle expensive work — scroll can fire dozens of times per second.
  5. Remove with .off("scroll", handler) — not .unbind().
PieceRequired?Role
TargetYeswindow or a scrollable element
handlerFor bind formfunction(event)
eventDataOptional (1.4.3+)Extra data as event.data
ThrottleRecommendedLimit how often expensive work runs

Pseudocode

Pseudocode
call $("#el").scroll(handler)
    → internally: $("#el").on("scroll", handler)

call $("#el").scroll()
    → internally: $("#el").trigger("scroll")

when scroll position changes:
    fire scroll on target
        for each registered handler:
            call handler(event)

to migrate:
    .scroll(fn)      → .on("scroll", fn)
    .scroll(data, fn) → .on("scroll", data, fn)
    .scroll()        → .trigger("scroll")

Cheat Sheet

Quick map from the deprecated shorthand to modern APIs.

TopicDetail
Legacy bind$("#el").scroll(handler) ⚠ deprecated 3.3
Modern bind$("#el").on("scroll", handler)
Legacy trigger$("#el").scroll()
Modern trigger$("#el").trigger("scroll")
Unbind$("#el").off("scroll" [, handler])
Signaturefunction(event)
SinceMethod 1.0 · eventData 1.4.3 · deprecated 3.3
Not the same.scrollTop() gets/sets position

Live Preview

Run the legacy .scroll() shorthand (still available in jQuery 3.x) and watch the handler update the log.

Demo uses deprecated .scroll(). Prefer .on("scroll") for new code. Scroll the box or click Trigger.

Result
Ready — scroll the box or click Run.

jQuery Examples

Short, copy-ready snippets using the legacy shorthand. Prefer .on("scroll") for new projects.

Example 1 — Basic $("#target").scroll(fn)

Canonical legacy pattern: append a message each time scroll fires.

jQuery
$("#target").scroll(function () {
  $("#log").append("Handler for scroll called. ");
});
Try It Yourself

How It Works

  1. Bind. .scroll(fn) on #target registers a handler.
  2. Delegate. jQuery routes it to .on("scroll", fn) internally.
  3. Scroll. Wheel, bar, keys, or touch all fire the same event.
  4. Append. Each firing adds another message fragment.

Example 2 — .scroll(eventData, handler)

Pass extra data (since 1.4.3). Modern form: .on("scroll", data, fn).

jQuery
$("#target").scroll({ label: "panel" }, function (event) {
  $("#out").text(
    event.data.label + ": " + $(this).scrollTop() + "px"
  );
});
Try It Yourself

How It Works

  1. Data. The object becomes event.data inside the handler.
  2. Scroll. Position change fires the event.
  3. Read. Use event.data.label plus .scrollTop().
  4. Migrate. Swap to .on("scroll", data, fn) when refactoring.

Example 3 — No-arg .scroll() Trigger

Fire the event programmatically. Prefer .trigger("scroll") today.

jQuery
$("#target").scroll(function () {
  $("#out").text("Handler for scroll called.");
});

$("#run").on("click", function () {
  $("#target").scroll(); // legacy trigger
});
Try It Yourself

How It Works

  1. Bind. The handler is registered first.
  2. Click. No-arg .scroll() triggers the event.
  3. Run. Bound handlers execute immediately.
  4. Migrate. Replace with .trigger("scroll") in new code.

Example 4 — Migrate to .on("scroll")

Both bind the same event — .on() is the recommended API for new code.

jQuery
// Legacy — deprecated since jQuery 3.3
$("#target").scroll(function () {
  $("#out").text("Legacy: .scroll(function(){ ... }).");
});

// Modern — use for new code
$("#target").on("scroll", function () {
  $("#out").text("Modern: .on('scroll', function(){ ... }).");
});
Try It Yourself

How It Works

  1. Same event. Both register handlers for scroll.
  2. Sugar. .scroll(fn) already calls .on("scroll", fn).
  3. Rename. Migration is a straight API change for simple bindings.
  4. 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);
  }
});
Try It Yourself

How It Works

  1. Count raw. Every scroll event increments raw.
  2. Gate. Expensive work runs only if 150 ms have passed.
  3. Compare. Throttled runs stay far below raw event count.
  4. 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.

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 Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All 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.

Performance Notes

ApproachCostBest for
Light log / scrollTop readCheapDebugging, simple labels
Throttled progress / sticky checkCheap–moderateLive UI while scrolling
Heavy DOM work every scrollExpensiveAvoid — throttle or debounce

Legacy and modern binds have the same cost. Keep handlers light, and throttle anything that measures or redraws the DOM.

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).

Next: jQuery Attributes

Continue with attribute helpers like .attr() and .prop().

Attributes hub →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful