jQuery .undelegate() Method

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

What Is .undelegate()?

.undelegate() (since 1.4.2) removes handlers attached with .delegate() on a root element. Filter by selector, event type, handler, or namespace. It is deprecated since 3.0 — use .off() instead.

Remember
// Legacy (deprecated since 3.0)
$("body").delegate("p", "click", fn);
$("body").undelegate("p", "click", fn);

// Modern — argument order swaps for .off()
$("body").on("click", "p", fn);
$("body").off("click", "p", fn);
NeedUse
New code.off(events [, selector] [, handler])
Legacy remove one.undelegate(selector, type, handler) ⚠
Legacy remove type.undelegate("click") ⚠
Legacy remove all.undelegate() ⚠
By namespace.undelegate(".ns") → .off(".ns")

How to Use .undelegate()

Call it on the same root you used with .delegate(), and match the selector exactly.

  1. Attach with $(root).delegate(selector, events, handler).
  2. Remove with $(root).undelegate(selector, events, handler) on that same root.
  3. Pass the same function reference when removing one specific handler.
  4. Use a namespace (e.g. click.whatever) for grouped cleanup with .undelegate(".whatever").
  5. In new code, migrate to .on() / .off() and swap the event/selector order.
PieceRequired?Role
RootYesSame element used with .delegate()
selectorOftenDescendant filter — must match the bind
eventTypeOftene.g. "click" or "click.ns"
handlerOptionalSame function reference to remove one handler

Pseudocode

Pseudocode
attach:
  $(root).delegate(selector, eventType, handler)
      → store delegated handler on root

remove one:
  $(root).undelegate(selector, eventType, handler)
      → drop that exact entry

remove by type:
  $(root).undelegate("click")
      → drop all delegated click handlers on root

remove by namespace:
  $(root).undelegate(".whatever")
      → drop all handlers under that namespace

remove all delegated:
  $(root).undelegate()
      → clear every .delegate() entry on root

migrate:
  .undelegate(sel, type, fn)  →  .off(type, sel, fn)

Cheat Sheet

Quick map from legacy .undelegate() to modern .off().

TopicDetail
Legacy remove$(root).undelegate(sel, type [, fn]) ⚠
Modern remove$(root).off(type, sel [, fn])
No args.undelegate() → all delegated on root
Namespace.undelegate(".ns") → .off(".ns")
Since1.4.2 · namespace 1.6 · deprecated 3.0
Pair with.delegate()
ReturnsjQuery (chainable)
Not forDirect .bind() handlers — use .unbind() / .off()

Live Preview

Bind a delegated click with legacy .delegate(), then remove it with .undelegate().

Demo uses deprecated APIs. Prefer .on() / .off() for new code. Click the target after binding.

Result
Ready — Run "delegate click", then click Target.

jQuery Examples

Short legacy demos. Prefer .off() for new projects — each example notes the modern equivalent.

Example 1 — Bind then Undelegate

Official pattern: attach with .delegate(), remove with .undelegate().

jQuery
function aClick() {
  $("#log").text("Delegated click ran!");
}

$("#bind").on("click", function () {
  $("body").delegate("#theone", "click", aClick);
  $("#theone").text("Can Click!");
});

$("#unbind").on("click", function () {
  $("body").undelegate("#theone", "click", aClick);
  $("#theone").text("Does nothing...");
});
Try It Yourself

How It Works

  1. Delegate. The handler is stored on body for #theone clicks.
  2. Bubble. Clicks on the target bubble up and run aClick.
  3. Undelegate. The same root, selector, type, and function remove it.
  4. Migrate. Prefer $("body").off("click", "#theone", aClick).

Example 2 — Remove All Delegated Handlers

Official pattern: .undelegate() with no arguments on the root.

jQuery
$("#list").delegate("li", "click", function () {
  $("#log").text("Click: " + $(this).text());
});

$("#off-all").on("click", function () {
  $("#list").undelegate();
  $("#log").text("All delegated handlers removed.");
});
Try It Yourself

How It Works

  1. Root. Handlers were delegated on #list.
  2. Clear. No-arg .undelegate() drops every delegated entry on that root.
  3. Scope. Direct handlers on #list itself are not the target of this call.
  4. Migrate. Prefer $("#list").off() carefully, or .off("click", "li") for precision.

Example 3 — Remove by Event Type

Official pattern: .undelegate("click") removes delegated clicks only.

jQuery
$("#list").delegate("li", "click", function () {
  $("#log").text("Delegated click ran.");
});
$("#list").delegate("li", "mouseenter", function () {
  $("#log").text("Delegated mouseenter ran.");
});

$("#unbind-click").on("click", function () {
  $("#list").undelegate("click");
  $("#log").text("Delegated click removed. Hover still works.");
});
Try It Yourself

How It Works

  1. Two types. Click and mouseenter are both delegated on #list.
  2. Filter. One-arg .undelegate("click") targets click only.
  3. Keep others. mouseenter remains until you remove it too.
  4. Migrate. Prefer $("#list").off("click", "li").

Example 4 — Remove One Handler by Reference

Official pattern: pass the same function used with .delegate().

jQuery
var foo = function () { $("#log").append(" [foo]"); };
var bar = function () { $("#log").append(" [bar]"); };

$("body").delegate("p", "click", foo);
$("body").delegate("p", "click", bar);

$("#remove-foo").on("click", function () {
  $("body").undelegate("p", "click", foo);
});
Try It Yourself

How It Works

  1. Two handlers. Both listen for delegated p clicks on body.
  2. Same reference. foo must be the identical function object.
  3. Selective. Only foo is removed; bar stays.
  4. Migrate. Prefer $("body").off("click", "p", foo).

Example 5 — Remove by Namespace

Official pattern: clear every handler under .whatever in one call.

jQuery
var foo = function () {
  $("#log").text("Validator ran");
};

$("form").delegate(":button", "click.whatever", foo);
$("form").delegate("input[type='text']", "keypress.whatever", foo);

$("#off-ns").on("click", function () {
  $("form").undelegate(".whatever");
});
Try It Yourself

How It Works

  1. Namespace. Events are bound as click.whatever and keypress.whatever.
  2. Group. Both share the .whatever namespace.
  3. Clear. .undelegate(".whatever") removes the whole group.
  4. Migrate. Prefer $("form").off(".whatever").

Edge Cases & Pitfalls

Watch for these when reading or migrating legacy delegation code.

deprecated

Do not use in new code

Deprecated since 3.0. Prefer .off() with the modern argument order.

root

Same root as .delegate()

Removing on the wrong element leaves the handler alive. Match the bind root.

selector

Selector string must match

"#theone" and "button#theone" are different keys — copy the bind selector exactly.

order

Migration swaps arguments

.undelegate(sel, type, fn) → .off(type, sel, fn). Getting the order wrong fails silently.

Browser Support

.undelegate() has been part of jQuery since 1.4.2 (namespace form since 1.6). It is deprecated since 3.0 but still functional in jQuery 3.x. Prefer .off().

✓ Deprecated · jQuery 1.4.2+

jQuery .undelegate()

Works wherever your loaded jQuery version runs. Treat it as a legacy counterpart to .delegate() — migrate to .on() / .off() when updating code.

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
.undelegate() Legacy API

Bottom line: Safe in legacy pages. For new apps, attach with .on(events, selector, handler) and remove with .off(events, selector, handler).

Performance Notes

ApproachCostBest for
Remove one handler by referenceCheapPrecise cleanup
Namespace removeCheapGrouped feature teardown
No-arg .undelegate()Cheap–moderateBroad cleanup — avoid overuse

Delegation itself is efficient for dynamic lists. Removing unused handlers avoids leaked listeners — namespaces make cleanup easy.

Key Takeaways

  • Role: remove handlers attached with .delegate().
  • Migrate: .off(type, selector [, fn]) — preferred since 1.7 / deprecated 3.0.
  • Match: same root, selector, and function reference as the bind.
  • Namespace: .undelegate(".ns") clears a whole group at once.

One line: .undelegate() is deprecated sugar for removing .delegate() handlers — use .off().

Frequently Asked Questions

.undelegate() removes event handlers that were attached with .delegate() on a root element. It can filter by descendant selector, event type, handler function reference, or namespace. Prefer .off() in new code.
Yes, it still works in jQuery 3.x but has been deprecated since jQuery 3.0. Do not use it in new projects. Replace .delegate() / .undelegate() with .on() / .off().
Swap parameter order: $("body").undelegate("p", "click", fn) becomes $("body").off("click", "p", fn). Namespace cleanup: .undelegate(".whatever") becomes .off(".whatever"). Use the same root element as .delegate().
.undelegate() removes delegated handlers from .delegate(). .unbind() removes direct handlers from .bind(). Both are deprecated; .off() replaces both.
If you bound with .delegate("#theone", "click", fn), call .undelegate("#theone", "click", fn) on the same root. A mismatched selector or wrong root will not remove the handler.
All delegated event handlers on the matched root elements are removed. It does not remove direct .bind() / .on() handlers on those elements — only delegation entries from .delegate().

Next: .live() method

See another legacy delegation API and how it maps to .on().

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

8 people found this page helpful