.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);
Call it on the same root you used with .delegate(), and match the selector exactly.
Attach with $(root).delegate(selector, events, handler).
Remove with $(root).undelegate(selector, events, handler) on that same root.
Pass the same function reference when removing one specific handler.
Use a namespace (e.g. click.whatever) for grouped cleanup with .undelegate(".whatever").
In new code, migrate to .on() / .off() and swap the event/selector order.
Piece
Required?
Role
Root
Yes
Same element used with .delegate()
selector
Often
Descendant filter — must match the bind
eventType
Often
e.g. "click" or "click.ns"
handler
Optional
Same 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)
Reference
Cheat Sheet
Quick map from legacy .undelegate() to modern .off().
Before: button click / keypress run validator
After: All .whatever delegated handlers removed
How It Works
Namespace. Events are bound as click.whatever and keypress.whatever.
Group. Both share the .whatever namespace.
Clear..undelegate(".whatever") removes the whole group.
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.
Compatibility
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 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
.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).
Analysis
Performance Notes
Approach
Cost
Best for
Remove one handler by reference
Cheap
Precise cleanup
Namespace remove
Cheap
Grouped feature teardown
No-arg .undelegate()
Cheap–moderate
Broad cleanup — avoid overuse
Delegation itself is efficient for dynamic lists. Removing unused handlers avoids leaked listeners — namespaces make cleanup easy.
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().