jQuery .change() Method

Beginner
⚠️ Deprecated since 3.3
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Form events

What You’ll Learn

The .change() method is jQuery’s legacy shorthand for binding and triggering the change event. This tutorial covers .change(handler) since 1.0, .change(eventData, handler) since 1.4.3, no-argument .change() as a trigger, migration to .on("change") and .trigger("change"), and why the binding form is deprecated since jQuery 3.3. For the modern change event API, see the jQuery change event tutorial.

01

.change(fn)

Bind handler

02

eventData

Since 1.4.3

03

.change()

Trigger event

04

.on()

Modern bind

05

.trigger()

Modern fire

06

Deprecated

Since 3.3

Introduction

Older jQuery form scripts often react to dropdown and input updates with a single short call: $("#country").change(function(){ ... }). Before jQuery 1.7 unified events with .on() and .off(), every common event had a matching shorthand — and .change() was the go-to for select boxes and text fields.

Understanding .change() matters when maintaining legacy themes, admin panels, and Stack Overflow snippets. The method does two jobs: with a function argument it binds; with no arguments it triggers. Modern jQuery splits those roles — .on("change", handler) for binding and .trigger("change") for firing.

Understanding the .change() Method

The official jQuery API describes .change() as a way to bind an event handler to the change event, or trigger that event on an element. When you pass a handler, jQuery registers it on each matched input, select, or textarea and calls it when the value actually changes — the same change event that .on("change") handles today.

When you call .change() with no arguments, jQuery synthetically fires change on each matched element. This is the legacy trigger shorthand — equivalent to .trigger("change"). It is commonly chained after .val() because setting a value with script does not fire change automatically.

⚠️
Deprecated since jQuery 3.3

Do not use .change(handler) or .change(eventData, handler) in new code. Replace them with .on("change", handler) or .on("change", eventData, handler). Replace no-argument .change() with .trigger("change"). For select timing, .val() behavior, and delegation, read the jQuery change event tutorial.

📝 Syntax

The .change() method has three signatures from the official jQuery API. The binding forms are deprecated; the trigger form remains valid but .trigger("change") is preferred:

1. Bind a handler — .change( handler ) (since 1.0, deprecated 3.3)

jQuery
.change( handler )
  • handler — function executed each time change fires: function( event ) { ... }.
  • Returns the jQuery object for chaining.
  • Modern replacement: .on( "change", handler ).

2. Bind with eventData — .change( [eventData], handler ) (since 1.4.3, deprecated 3.3)

jQuery
.change( [eventData], handler )
  • eventData — optional object available in the handler as event.data.
  • Modern replacement: .on( "change", eventData, handler ).

3. Trigger the event — .change() (since 1.0)

jQuery
.change()
  • No arguments — triggers change on every matched element.
  • Runs bound change handlers — use after .val() when script updates a field.
  • Preferred replacement: .trigger( "change" ).

Official jQuery API migration note

jQuery
// Deprecated binding
$( "select" ).change( function() {
  alert( "Handler for `change` called." );
} );

// Modern binding
$( "select" ).on( "change", function() {
  alert( "Handler for `change` called." );
} );

// Deprecated trigger (common after .val())
$( "#country" ).val( "US" ).change();

// Modern trigger
$( "#country" ).val( "US" ).trigger( "change" );

Return value

  • All .change() signatures return the original jQuery object for chaining.
  • Handler return values are ignored unless you use return false (equivalent to preventDefault() + stopPropagation()).

⚡ Quick Reference

GoalLegacy (.change)Modern replacement
Bind change handler$("#country").change(fn)$("#country").on("change", fn)
Pass data to handler$("select").change({ id: 1 }, fn)$("select").on("change", { id: 1 }, fn)
Trigger change programmatically$("#country").change()$("#country").trigger("change")
After .val() update$("#tier").val("pro").change()$("#tier").val("pro").trigger("change")
Initial draw on load$("select").change(fn).change()$("select").on("change", fn).trigger("change")
Remove change handlers$("#country").off("change")$("#country").off("change")
Delegated change on selects$("#form").on("change", "select", fn) — not available via .change()

📋 .change() vs .on("change") vs .trigger("change") vs .off("change")

Four related APIs — know which one binds, which one fires, and which one removes handlers.

.change()
deprecated

Legacy bind (.change(fn)) or trigger (.change()) — use modern APIs for new code

.on("change")
bind

Modern binding since 1.7 — supports eventData and delegation on dynamic forms

.trigger("change")
fire

Programmatically run handlers — clearer than no-arg .change()

.off("change")
remove

Unbind handlers — pair with .on("change") when cleaning up or in SPAs

Examples Gallery

Five examples cover binding, eventData, triggering after .val(), migration from .change() to .on("change"), and init chaining. Use the Try-it links to run each snippet. Remember: binding with .change(handler) is deprecated — these demos show legacy syntax you will encounter in older code.

📚 Binding & Triggering

Legacy .change() signatures for dropdown handlers and programmatic triggers.

Example 1 — Bind Handler with .change(handler)

The canonical legacy pattern — update UI when the user picks a new dropdown option.

jQuery
$( "#country" ).change( function() {
  var label = $( "#country option:selected" ).text();
  $( "#out" ).text( "Selected: " + label );
} );
Try It Yourself

How It Works

.change(fn) registers the function on the select. jQuery internally routes this to .on("change", fn). For dropdowns, change fires as soon as the user makes a new selection.

Example 2 — Pass eventData with .change(eventData, handler)

Since jQuery 1.4.3, pass metadata before the handler — it arrives as event.data.

jQuery
$( ".plan-select" ).change( { currency: "USD" }, function( event ) {
  var plan = $( this ).val();
  $( "#out" ).text(
    "Plan: " + plan + " | currency: " + event.data.currency
  );
} );
Try It Yourself

How It Works

jQuery stores the { currency: "USD" } object and injects it into event.data when any matched select changes. Modern equivalent: .on("change", { currency: "USD" }, fn).

Example 3 — Trigger Change After .val() with No-Argument .change()

Setting a value with .val() does not fire change — chain .change() to run handlers.

jQuery
$( "#tier" ).change( function() {
  $( "#out" ).text( "Tier is now: " + $( this ).val() );
} );

$( "#set-pro" ).click( function() {
  $( "#tier" ).val( "pro" ).change();
} );
Try It Yourself

How It Works

This is one of the most common legacy patterns. Script sets the select value silently; .change() with no arguments tells jQuery to run bound handlers as if the user had changed the field.

📈 Migration & Init

Compare legacy and modern APIs, and initialize UI with chained .change().

Example 4 — Migration: .change(fn) vs .on("change", fn)

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

jQuery
$( "#legacy" ).change( function() {
  $( "#out" ).text( "Legacy: .change(function(){ ... }) — deprecated since jQuery 3.3." );
} );

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

How It Works

Under the hood, .change(fn) calls .on("change", fn). Migration is a straight rename. The advantage of .on() is delegation — $("#form").on("change", "select", fn) — which .change() cannot do.

Example 5 — Init Chain: .change(fn).change()

Bind a handler and immediately trigger it so the UI reflects the default selection on page load.

jQuery
$( "#flavor" )
  .change( function() {
    var text = $( "#flavor option:selected" ).text();
    $( "#summary" ).text( "You picked: " + text );
  } )
  .change();
Try It Yourself

How It Works

The first .change(fn) binds; the second .change() with no args triggers. Because both return the jQuery object, they chain fluently. This official jQuery pattern avoids a blank summary before the user interacts.

🚀 Common Use Cases

  • Reading legacy code — recognize $("#country").change(fn) as equivalent to .on("change", fn) in older form scripts.
  • Dependent dropdowns — legacy tutorials bind .change() to reload state lists when country changes.
  • Post-.val() sync$("#plan").val("enterprise").change() after AJAX prefills a form.
  • Shared eventData$(".filter").change({ table: "#users" }, fn) passes context without closures.
  • Initial UI draw.change(fn).change() on load to reflect default selections.
  • WordPress & admin UIs — many themes still use .change() — know how to migrate safely.

🔄 How .change() Routes Through jQuery

1

You call .change()

With a function argument, jQuery treats it as a bind request. With no arguments, it treats it as a trigger request.

dispatch
2

Bind path

.change(handler) delegates internally to .on("change", handler) — stored in jQuery’s event system.

.on("change")
3

Trigger path

No-arg .change() delegates to .trigger("change") — bound handlers run; common after .val().

.trigger("change")
4

jQuery object returned

Both paths return the original collection for chaining — .change(fn).change() works the same as .on("change", fn).trigger("change").

📝 Notes

  • Deprecated since jQuery 3.3 — do not use .change(handler) or .change(eventData, handler) in new code. Use .on("change") instead.
  • Bind with .change(handler) since jQuery 1.0; eventData form since 1.4.3.
  • No-argument .change() triggers the event since jQuery 1.0 — prefer .trigger("change").
  • .change() does not support event delegation — use .on("change", selector, fn) for dynamic forms.
  • .val(newValue) does not fire change — chain .change() or .trigger("change") afterward.
  • Text inputs: change fires on blur only when value changed; selects fire immediately.
  • For the full modern change event guide — timing, bubbling, and validation — see the jQuery change event tutorial.

Browser Support

The underlying change event is a standard DOM form event supported in every browser jQuery targets. The .change() method itself is a jQuery API — it works in jQuery 1.x, 2.x, and 3.x. Binding via .change(handler) is deprecated since 3.3 but still functional; triggering via no-arg .change() also remains supported.

jQuery 1.0+

jQuery .change() method

Supported across all jQuery versions you are likely to maintain. Deprecated binding since 3.3 — use .on('change') for new projects. Native equivalent for binding: element.addEventListener('change', fn). Native equivalent for trigger: dispatchEvent or .trigger('change').

100% With jQuery loaded
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
.change() Legacy API

Bottom line: Safe in legacy jQuery projects. Migrate bindings to .on('change') and triggers to .trigger('change') when updating form scripts.

Conclusion

The jQuery .change() method is the legacy shorthand for binding and triggering change handlers. Use .change(handler) or .change(eventData, handler) to bind — both deprecated since jQuery 3.3. Use no-argument .change() to trigger — equivalent to .trigger("change"), especially after .val() updates.

For new code, prefer .on("change", fn) for binding and .trigger("change") for programmatic firing. When you encounter .change() in older projects, recognize it, understand it, and migrate when practical. For select timing, delegation, and the complete modern workflow, continue with the jQuery change event tutorial.

💡 Best Practices

✅ Do

  • Use .on("change", handler) for all new change bindings
  • Use .trigger("change") instead of no-arg .change()
  • Chain .trigger("change") after .val() when handlers must run
  • Migrate .change(fn) to .on("change", fn) when refactoring legacy files
  • Read the modern change event tutorial for delegation patterns

❌ Don’t

  • Write new dropdown logic with deprecated .change(handler)
  • Assume .val("x") runs change handlers — trigger manually
  • Confuse .change(fn) (bind) with .change() (trigger)
  • Use .unbind("change") — it is also deprecated; use .off("change")
  • Copy deprecated patterns from old tutorials without modernizing them

Key Takeaways

Knowledge Unlocked

Six things to remember about .change()

Legacy bind, modern migrate.

6
Core concepts
data 02

eventData

Since 1.4.3

Handler
() 03

.change()

Trigger

No args
.on 04

.on("change")

Modern

Replace
.val 05

After .val()

Trigger

Pitfall
3.3 06

Deprecated

Since 3.3

Migrate

❓ Frequently Asked Questions

The .change() method has two roles. With a handler argument — .change(handler) or .change(eventData, handler) — it binds a function that runs when the matched element's value changes. With no arguments — .change() — it triggers the change event on each matched element, running bound handlers. Both forms have been part of jQuery since 1.0; the binding form is deprecated since 3.3.
Yes — the binding signatures .change(handler) and .change(eventData, handler) are deprecated since jQuery 3.3. Use .on('change', handler) or .on('change', eventData, handler) instead. The no-argument .change() trigger form still works but .trigger('change') is clearer and preferred in modern code. Existing legacy code continues to run in jQuery 3.x; migrate when you touch those files.
.change(handler) registers a callback — it does not fire the event immediately. .change() with no arguments triggers the change event programmatically on every matched element, the same as .trigger('change'). The handler form is deprecated for binding; the no-arg form is a trigger shorthand. Use .change() after .val() when script updates a field and handlers must run.
Replace .change(fn) with .on('change', fn). Replace .change(data, fn) with .on('change', data, fn). Replace no-arg .change() with .trigger('change'). Replace .unbind('change') cleanup with .off('change'). Under the hood, .change(handler) already delegates to .on('change') — migration is a straight rename with no behavior change for simple bindings.
Yes. jQuery 3.x keeps .change() for backward compatibility with jQuery 1.x and 2.x codebases. It still binds and triggers correctly. The API docs mark it deprecated to steer new projects toward .on() and .trigger(). Do not use .change(handler) in new code — prefer the modern API covered in the jQuery change event tutorial.
No. Setting a value with .val('new') does not fire change automatically — whether you bound with .change(fn) or .on('change', fn). After programmatic updates, call .change() (trigger shorthand) or .trigger('change') explicitly: $('#country').val('US').trigger('change').
Did you know?

jQuery unified event binding in version 1.7 with .on() and .off(), replacing shorthand methods like .change(), .blur(), and .bind(). The old .change(handler) still works but is deprecated since 3.3 — under the hood it delegates to .on("change"). The no-argument .change() trigger form is still common in legacy code after .val() updates, though .trigger("change") is clearer in modern projects.

Learn the modern change event API

Prefer .on("change") and .trigger("change") — full tutorial with five try-it labs.

change event tutorial →

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.

6 people found this page helpful