The .undelegate() method removes delegated event handlers attached with .delegate(). Deprecated since jQuery 3.0 and superseded by .off() since 1.7, it still appears in legacy plugins and themes. This tutorial covers all official signatures, five worked examples, namespace cleanup, migration with swapped argument order, and why new code should use .off().
01
Syntax
sel, type, fn
02
Pair
Undoes .delegate()
03
Root
Same element
04
Selector
Must match
05
Migrate
Swap to .off()
06
Dep 3.0
Legacy only
Fundamentals
Introduction
Event delegation lets you attach one handler on a stable parent and filter events from matching descendants. jQuery introduced .delegate() in version 1.4.2 for this pattern, with .undelegate() as its removal counterpart. Together they predated the unified .on() / .off() API from jQuery 1.7.
As of jQuery 3.0, .undelegate() is deprecated. It still runs in jQuery 3.x for backward compatibility, but every new project should use .off(eventType, selector, handler) on the same root element — note the reversed argument order compared to .undelegate(selector, eventType, handler).
Concept
Understanding .undelegate()
.undelegate() operates on the root element where delegation was attached — not on the descendant that triggers the event. If you called $("body").delegate("#theone", "click", fn), you must call $("body").undelegate("#theone", "click", fn) on body, not on #theone.
The descendant selector must exactly match what was passed to .delegate(). Handler removal by function reference requires the same function object used during binding — anonymous inline functions cannot be removed unless you keep a reference.
💡
Beginner Tip
Remember the argument order difference: .delegate(selector, type, fn) but .off(type, selector, fn). When migrating, swap selector and event type — everything else stays the same.
Foundation
📝 Syntax
Five signatures from the official jQuery API (all deprecated since 3.0):
1. Remove all delegated — .undelegate()
jQuery
.undelegate()
2. By selector and type — .undelegate( selector, eventType [, handler ] )
// Legacy — selector FIRST
$( "#list" ).delegate( "li", "click", fn );
$( "#list" ).undelegate( "li", "click", fn );
// Modern — event type FIRST
$( "#list" ).on( "click", "li", fn );
$( "#list" ).off( "click", "li", fn );
// Namespace — same on both APIs
$( "form" ).undelegate( ".whatever" );
$( "form" ).off( ".whatever" );
Return value
Returns the original jQuery object for chaining.
Only removes handlers attached via .delegate() on the matched root elements.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Remove all delegated handlers
$("#list").undelegate()
Remove all delegated clicks
$("#list").undelegate("click")
Remove one delegated handler
$("body").undelegate("p", "click", fn)
Remove namespace handlers
$("form").undelegate(".whatever")
Modern equivalent
$("#list").off("click", "li", fn)
Status
Deprecated jQuery 3.0
Compare
📋 .undelegate() vs .off() vs .unbind() vs .die()
Four unbinding methods from different jQuery eras. Only .off() should be used in new projects.
.undelegate()
.delegate() pair
Root delegation only — deprecated 3.0
.off()
.on() pair
Direct + delegated — recommended
.unbind()
.bind() pair
Direct handlers only — deprecated 3.0
.die()
.live() pair
Document-level — removed 1.9
Hands-On
Examples Gallery
All five examples follow the official jQuery API documentation for .undelegate(). Try-it labs use .delegate() / .undelegate() on the legacy API to match the docs.
📚 Official API Examples
Five patterns from api.jquery.com/undelegate/.
Example 1 — Delegate and Undelegate Click on #theone
The official interactive demo: body.delegate("#theone", "click", aClick) then body.undelegate("#theone", "click", aClick).
Delegation attaches on body for clicks matching #theone. .undelegate() requires the same root, selector, event type, and function reference used in .delegate().
Example 2 — Remove All Delegated Handlers
Calling .undelegate() with no arguments clears every delegated handler on the matched root elements.
p is delegation root with handlers on descendants
$("p").undelegate() → all delegated entries removed
Direct .bind() handlers on p itself are NOT removed
How It Works
When p is the delegation root, .undelegate() strips all descendant-filtered handlers registered on it via .delegate().
Example 3 — Remove All Delegated Click Handlers
Pass only the event type to remove every delegated click handler on the root.
#list has delegated click on li + mouseenter on li
$("#list").undelegate("click") → click delegation gone
Delegated mouseenter still works
Modern: $("#list").off("click")
How It Works
A single-argument string is treated as an event type, removing all delegated handlers of that type from the root regardless of descendant selector.
Example 4 — Remove One Handler by Function Reference
Official pattern: pass the same foo function given to .delegate().
jQuery
var foo = function() {
// Code to handle some kind of event
};
$( "body" ).delegate( "p", "click", foo );
$( "body" ).undelegate( "p", "click", foo );
Two handlers delegated on body for click p
.undelegate("p", "click", handlerA) removes only handlerA
handlerB still runs on p clicks
Modern: body.off("click", "p", handlerA)
How It Works
Surgical removal requires matching root, selector, event type, and function reference. Store handlers in named variables for reliable cleanup.
Example 5 — Remove Handlers by Namespace
Plugin-friendly cleanup: bind under .whatever, remove all at once.
jQuery
var foo = function() {
// Code to handle some kind of event
};
$( "form" ).delegate( ":button", "click.whatever", foo );
$( "form" ).delegate( "input[type='text']", "keypress.whatever", foo );
$( "form" ).undelegate( ".whatever" );
click.whatever on :button + keypress.whatever on input
.undelegate(".whatever") removes BOTH
Other delegated handlers without .whatever untouched
Modern: form.off(".whatever")
How It Works
Passing only a namespace string (starting with .) removes every delegated handler with that namespace on the root, across all event types and selectors.
Applications
🚀 Why You Still See .undelegate()
Legacy jQuery plugins — delegated bind/unbind before .on() existed.
Maintenance & migration — read old code before swapping to .off().
Toggle delegation — official bind/unbind button demo from Example 1.
Widget teardown — .undelegate(".myPlugin") in destroy methods.
Understanding .off() — see why argument order flipped from legacy delegation.
Pair with .delegate() — the complete legacy delegation story.
🧠 How .undelegate() Finds Handlers to Remove
1
Identify root
jQuery looks at the matched root element(s) where .delegate() originally attached handlers.
Root
2
Apply filters
Descendant selector, event type, namespace, or handler function narrow which delegation entries to remove.
Match
3
Detach matches
Matching delegated handlers are removed from the root’s event registry.
Remove
4
🔄
Migrate to .off()
Same logic in .off(type, selector, fn) — swap selector and type compared to .undelegate().
Important
📝 Notes
.undelegate() was added in jQuery 1.4.2; namespace-only form since 1.6; deprecated in 3.0.
Only removes handlers from .delegate() — not .live() (use .die()) or .bind() (use .unbind()).
Argument order is selector first, event type second — opposite of .off().
Call .undelegate() on the delegation root, not on the descendant that receives clicks.
Proxied handlers: unbinding one proxied function may affect others; prefer namespaces.
Modern replacement: .off(eventType, selector, handler) on the same root element.
Compatibility
Browser Support
.undelegate() is a deprecated jQuery method available in jQuery 1.4.2+ through 3.x. It works in browsers your jQuery version supports but should not be used in new code. Use .off() with swapped argument order instead.
✓ Deprecated 3.0
jQuery .undelegate()
Still executes in jQuery 3.x for backward compatibility but deprecated since 3.0. Read and migrate legacy delegation code to .off(). Never use in new projects.
LegacyDeprecated API
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()Use .off()
Bottom line: Do not use .undelegate() in new jQuery code. Migrate .delegate() to .on() and .undelegate() to .off(), swapping selector and event type arguments.
Wrap Up
Conclusion
jQuery .undelegate() was the removal counterpart to .delegate() for root-level event delegation. Deprecated since version 3.0 and superseded by .off() since 1.7, it remains essential vocabulary for reading and migrating legacy jQuery code.
Every .undelegate(selector, type, fn) call maps directly to .off(type, selector, fn) on the same root. Pair this tutorial with the .delegate() and .off() tutorials for the full migration picture.
Migrate to .off(type, selector, fn) when updating legacy code
Call .undelegate() on the same root used for .delegate()
Match the descendant selector exactly between bind and unbind
Use namespaces: .undelegate(".myPlugin") for plugin teardown
Store handler references for targeted removal
❌ Don’t
Write new code with .delegate() / .undelegate()
Call .undelegate() on the descendant instead of the root
Confuse argument order with .off() during migration
Expect .undelegate() to remove .live() handlers
Try to unbind anonymous function copies by reference
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about .undelegate()
Legacy delegation unbind — migrate to .off().
6
Core concepts
📝01
.delegate() pair
Root only.
Legacy
sel02
Selector first
Then type.
Order
.off03
Swap args
For .off().
Migrate
fn04
By ref
Same function.
Rule
.ns05
Namespace
.undelegate(".ns")
Plugins
3.006
Deprecated
Don’t use new.
Status
❓ Frequently Asked Questions
.undelegate() removes event handlers that were attached with .delegate() on a root element. It filters by descendant selector, event type, handler function reference, or namespace. It only affects delegated handlers on the matched root — not direct .bind() handlers.
.undelegate() still works in jQuery 3.x but has been deprecated since jQuery 3.0. Do not use it in new code. Replace .delegate() / .undelegate() with .on() / .off(), swapping argument order for delegation.
Swap parameter order: $('body').undelegate('p', 'click', fn) becomes $('body').off('click', 'p', fn). Namespace cleanup is identical: .undelegate('.whatever') becomes .off('.whatever'). The root element must be the same as where .delegate() was called.
.undelegate() removes handlers attached with .delegate() — delegated handlers filtered by a descendant selector. .unbind() removes direct handlers attached with .bind() on the element itself. Both are deprecated; .off() replaces both.
If you bound with .delegate('#theone', 'click', fn), you must call .undelegate('#theone', 'click', fn) on the same root element. 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 handlers bound with .bind() on those elements — only delegation entries from .delegate().
Did you know?
When jQuery 1.7 unified event handling, .undelegate() and .unbind() were already marked as legacy — but developers kept using them for years because the argument-order swap to .off() felt confusing. The rule is simple: legacy delegation put the selector first; modern .off() puts the event type first.