jQuery .delegate() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Event delegation

What You’ll Learn

The .delegate() method attaches event handlers to descendants that match a selector — including elements added after the page loads. This tutorial covers syntax, five official jQuery API examples, how delegation differs from direct binding, migration to .on(), and pitfalls every beginner maintaining legacy code should know.

01

Syntax

.delegate(sel, type, fn)

02

Root element

Pick delegation context

03

Dynamic DOM

Future elements work

04

Migrate

Swap to .on()

05

vs .live()

Controllable root

06

Deprecated

Since jQuery 3.0

Introduction

Event delegation solves a common problem: you want click (or other) handlers on list items, table cells, or buttons that may not exist when your script first runs. Instead of binding to each child individually, you attach one handler on a parent and filter by a CSS selector.

jQuery introduced .delegate() in version 1.4.2 as the successor to .live(), giving you explicit control over which element acts as the delegation root. In jQuery 1.7, .on() unified direct and delegated binding; .delegate() was deprecated in 3.0 but remains available for reading and maintaining older codebases.

Understanding .delegate()

.delegate() does not attach a handler directly to every matching descendant. It listens on the jQuery collection you call it on (the root or delegation context). When an event bubbles up from a descendant that matches your selector, jQuery runs your handler with this set to that matched element.

Choose .delegate() when maintaining legacy jQuery projects. For new code, use the equivalent .on() call — same behavior, modern API, and no deprecation warnings.

💡
Beginner Tip

Think of $("#list").delegate("li", "click", fn) as “whenever a click bubbles through #list from an li, run fn.” New li elements added later are covered automatically.

📝 Syntax

Three overloads from the official jQuery API:

1. Basic form — .delegate( selector, eventType, handler ) (since 1.4.2)

jQuery
.delegate( selector, eventType, handler )
  • selector — filters descendants that may trigger the handler.
  • eventType — one or more space-separated events (e.g. "click", "keydown").
  • handlerfunction( event ) { ... } executed when a match occurs.

2. With eventData — .delegate( selector, eventType, eventData, handler )

jQuery
$( "#panel" ).delegate( "button", "click", { id: "save" }, function( event ) {
  console.log( event.data.id );  // "save"
} );

3. Events map — .delegate( selector, events ) (since 1.4.3)

jQuery
$( "table" ).delegate( "td", {
  click: function() { $( this ).toggleClass( "chosen" ); },
  mouseenter: function() { $( this ).addClass( "hover" ); },
  mouseleave: function() { $( this ).removeClass( "hover" ); }
} );

Official migration template

jQuery
// jQuery 1.4.3+ — deprecated since 3.0
$( elements ).delegate( selector, events, data, handler );

// jQuery 1.7+ — use this in new code
$( elements ).on( events, selector, data, handler );

Concrete example

jQuery
$( "table" ).delegate( "td", "click", function() {
  $( this ).toggleClass( "chosen" );
} );

// Modern equivalent:
$( "table" ).on( "click", "td", function() {
  $( this ).toggleClass( "chosen" );
} );

Return value

  • Returns the original jQuery object for chaining.
  • Remove delegated handlers with .undelegate() or, preferably, .off().

⚡ Quick Reference

GoalCode
Delegate click on list items$("#list").delegate("li", "click", fn)
Pass data to handler$("#list").delegate("li", "click", { id: 1 }, fn)
Multiple events (map)$("#list").delegate("li", { click: fn, mouseenter: fn2 })
Modern replacement$("#list").on("click", "li", fn)
Remove delegation$("#list").undelegate("li", "click") or .off("click", "li")
Added in / deprecated1.4.2 / deprecated 3.0

📋 .delegate() vs .on() vs .live() vs .bind()

Four jQuery event APIs from different eras. Know which one you are reading in legacy code and what to write today.

.delegate()
root.delegate(sel, type, fn)

Delegation with chosen root — deprecated 3.0

.on()
root.on(type, sel, fn)

Modern unified API since 1.7 — use this

.live()
$(sel).live(type, fn)

Document-level only — removed in 1.9

.bind()
$(el).bind(type, fn)

Direct binding only — no delegation

Examples Gallery

Examples 1–5 follow the official jQuery API documentation for .delegate(). Use the Try-it links to run each snippet in the browser. Snippets use .delegate() to match the legacy API; migrate to .on() when writing new code.

📚 Official API Demos

Core delegation patterns from api.jquery.com/delegate/.

Example 1 — Click a Paragraph to Add Another

.delegate() attaches a click handler to all paragraphs — even ones added after the initial bind.

jQuery
$( "body" ).delegate( "p", "click", function() {
  $( this ).after( "<p>Another paragraph! <span>with extra text</span></p>" );
} );
Try It Yourself

How It Works

Binding on body with selector "p" means any click that bubbles from a paragraph triggers the handler. Dynamically inserted paragraphs match the same rule without a second .delegate() call.

Example 2 — Alert Each Paragraph’s Text

Display paragraph text in an alert whenever it is clicked.

jQuery
$( "body" ).delegate( "p", "click", function() {
  alert( $( this ).text() );
} );
Try It Yourself

How It Works

Inside the delegated handler, this refers to the descendant that matched "p", not body. $(this).text() reads visible text from that paragraph.

📈 Controlling Default Actions

Stop link navigation while keeping or canceling event propagation.

Example 3 — Cancel Default and Bubbling with return false

Prevent anchor navigation and stop the event from bubbling further.

jQuery
$( "body" ).delegate( "a", "click", function() {
  return false;
} );
Try It Yourself

How It Works

Returning false from a jQuery event handler cancels the browser’s default action (following the link) and stops propagation. Prefer explicit event.preventDefault() in modern code when you only need to block the default.

Example 4 — Block Navigation with preventDefault()

Cancel only the default action — the event may still bubble to other handlers.

jQuery
$( "body" ).delegate( "a", "click", function( event ) {
  event.preventDefault();
} );
Try It Yourself

How It Works

event.preventDefault() stops the browser from following the hyperlink but does not automatically stop bubbling. Use event.stopPropagation() separately when you need to halt the bubble phase.

⚡ Custom Events

Delegation works for custom event names, not just native DOM events.

Example 5 — Delegate a Custom Event

Bind myCustomEvent on paragraphs and trigger it from a button.

jQuery
$( "body" ).delegate( "p", "myCustomEvent", function( e, myName, myValue ) {
  $( this ).text( "Hi there!" );
  $( "span" )
    .stop()
    .css( "opacity", 1 )
    .text( "myName = " + myName )
    .fadeIn( 30 )
    .fadeOut( 1000 );
} );

$( "button" ).on( "click", function() {
  $( "p" ).trigger( "myCustomEvent", [ "John", "Doe" ] );
} );
Try It Yourself

How It Works

Custom events triggered with .trigger() bubble like native events. The delegated handler on body catches myCustomEvent from any matching p. Extra arguments after the event name arrive as handler parameters.

🚀 Common Use Cases

  • Dynamic todo lists$("#tasks").delegate("li", "click", fn) covers items added via AJAX.
  • Data tables$("table").delegate("td", "click", fn) highlights cells without per-row binding.
  • Action menus — delegate on a toolbar container for buttons injected at runtime.
  • Legacy maintenance — read and refactor old plugins that still call .delegate().
  • Scoped delegation — limit handlers to a widget root instead of the entire document (unlike old .live()).
  • Migration audits — grep for .delegate( when upgrading to jQuery 3 with Migrate warnings enabled.

🧠 How .delegate() Handles an Event

1

User action

A click (or other event) occurs on a descendant element inside the delegation root.

Target
2

Bubble phase

The event travels upward from the target toward the root where .delegate() was called.

Bubble
3

Selector match

jQuery checks whether any element along the path matches your selector (e.g. "td").

Filter
4

Handler runs

Your function executes with this set to the matched descendant. event.delegateTarget is the root element.

📝 Notes

  • .delegate() was added in jQuery 1.4.2 and deprecated in 3.0. Prefer .on() for new code.
  • Parameter order differs from .on(): delegate puts selector first, then event type.
  • Unlike .live(), you choose the delegation root — handlers do not always attach at document.
  • Events handled by .delegate() propagate to the root; handlers below the root may run first and call stopPropagation().
  • Remove handlers with .undelegate() or the modern .off(eventType, selector).
  • Passing and handling eventData works the same way as with .on().
  • jQuery Migrate logs JQMIGRATE: jQuery.fn.delegate() is deprecated when this method is used on jQuery 3+.

Browser Support

.delegate() is a jQuery method, not a browser feature. It works wherever your jQuery version supports it. The method was added in jQuery 1.4.2, superseded by .on() in 1.7, and deprecated in 3.0 (still callable). Native event delegation uses element.addEventListener(type, fn, { capture: false }) with manual target checks.

jQuery 1.4.2+ · deprecated 3.0

jQuery .delegate()

Available in jQuery 1.4.2 through 3.x (deprecated). Removed from recommended usage since 1.7 when .on() arrived. Works in all browsers that run your chosen jQuery build — IE support depends on the jQuery major version (1.x supported IE6+; 2.x dropped IE6–8; 3.x targets IE9+ with patches).

Legacy Use .on() for new projects
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
.delegate() Deprecated

Bottom line: Safe to read in legacy codebases on jQuery 1.4.2+. For jQuery 3 upgrades, replace .delegate() with .on() and enable jQuery Migrate temporarily to catch remaining calls. Greenfield projects should never introduce .delegate().

Conclusion

jQuery .delegate() was an important step toward modern event delegation: one handler on a chosen root, filtered by selector, covering present and future descendants. Understanding it helps you maintain plugins, themes, and admin panels written before jQuery 1.7.

When you write new code or refactor old code, use .on(eventType, selector, handler) instead. The five official examples above map directly to .on() by swapping the first two arguments. Practice the Try-it labs until delegation feels natural — it remains one of the most practical patterns in jQuery and vanilla JavaScript alike.

💡 Best Practices

✅ Do

  • Migrate .delegate() to .on() when touching legacy files
  • Pick the smallest practical root element (a list, table, or widget container)
  • Use specific selectors ("li.task") to avoid accidental matches
  • Remove handlers with .off() when destroying widgets
  • Enable jQuery Migrate during jQuery 3 upgrades to catch deprecated calls

❌ Don’t

  • Introduce .delegate() in new projects
  • Confuse parameter order with .on() during migration
  • Delegate on body when a closer parent suffices
  • Assume this === event.target when children are nested
  • Forget that return false also stops propagation

Key Takeaways

Knowledge Unlocked

Six things to remember about .delegate()

Legacy delegation — and how to move forward.

6
Core concepts
🌳 02

Root

You pick context.

Scope
🔄 03

Dynamic

Future nodes work.

Pattern
.on 04

Migrate

Swap arg order.

Modern
3.0 05

Deprecated

Still callable.

Status
this 06

Matched child

Not the root.

Handler

❓ Frequently Asked Questions

.delegate(selector, eventType, handler) attaches a handler to one or more events for all elements matching selector — now or in the future — based on a specific set of root elements. You bind once on a parent; jQuery runs the handler when a descendant matching selector triggers the event.
.delegate() is deprecated as of jQuery 3.0 but still present. New code should use .on(eventType, selector, handler) instead. jQuery Migrate may warn when .delegate() is called. For jQuery 1.4.2 through 1.6, .delegate() was the recommended delegation API before .on() arrived in 1.7.
Swap the parameter order: $(elements).delegate(selector, events, data, handler) becomes $(elements).on(events, selector, data, handler). Example: $('table').delegate('td', 'click', fn) → $('table').on('click', 'td', fn). To remove handlers, replace .undelegate() with .off().
.live() always attached handlers at the document root — you could not choose where delegation started. .delegate() lets you pick the root element (e.g. a table or list). .live() was removed in jQuery 1.9; .delegate() was superseded by .on() in 1.7 and deprecated in 3.0.
Delegation binds one handler on a stable parent instead of many handlers on individual children. It works for elements added later via .append() or AJAX without rebinding. It also reduces memory use on long lists and tables.
Inside a delegated handler, event.delegateTarget is the element where the handler was attached — the root you called .delegate() or .on() on. event.currentTarget is the matched descendant (often the same as $(this)). See the event.delegateTarget tutorial for details.
Did you know?

jQuery 1.7 replaced four older methods — .bind(), .unbind(), .delegate(), and .undelegate() — with two unified methods: .on() and .off(). The only migration trick for delegation is swapping argument order: .delegate("td", "click", fn) becomes .on("click", "td", fn).

Next: .undelegate() Method

Remove delegated handlers attached with .delegate() — the legacy counterpart to .off() for delegation roots.

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