jQuery Event Delegation
Event delegation is a technique where you attach a single event listener to a parent element instead of attaching individual listeners to each child element. This is one of the most powerful and important patterns in jQuery — especially when elements are added to the page dynamically.
The Problem Without Event Delegation
Normally, when you attach a click event to elements, it only works for elements that exist at that moment. If you add new elements to the page later using JavaScript or AJAX, those new elements do not have the event.
HTML initially:
<ul id="taskList">
<li>Task 1</li>
<li>Task 2</li>
</ul>
jQuery:
$("li").click(function() {
$(this).css("text-decoration", "line-through");
});
// Later you add a new task:
$("#taskList").append("<li>Task 3</li>");
// Task 3 does NOT respond to click — it was not there when the event was attached!
The Solution — Event Delegation
Attach the event to the parent (or even document) and tell jQuery which child to listen for. jQuery checks if the click came from a matching child and runs your function only if it matches.
$(document).ready(function() {
$("#taskList").on("click", "li", function() {
$(this).css("text-decoration", "line-through");
});
});
Now even Task 3 (added later) responds to clicks — because the listener is on the parent #taskList, not on the li elements themselves.
Diagram: How Event Delegation Works
Without Delegation: ┌─────────────────────────────────┐ │ #taskList (no listener) │ │ ├── li Task 1 [listener ✓] │ │ ├── li Task 2 [listener ✓] │ │ └── li Task 3 [no listener ✗]│ (added later) └─────────────────────────────────┘ With Delegation: ┌─────────────────────────────────┐ │ #taskList [listener ✓] │ (parent catches all clicks) │ ├── li Task 1 │ ← click bubbles up to parent ✓ │ ├── li Task 2 │ ← click bubbles up to parent ✓ │ └── li Task 3 │ ← click bubbles up to parent ✓ └─────────────────────────────────┘ (works even if added later)
Event Bubbling — The Key Concept
When you click an element, the click event does not just stay on that element. It bubbles up the DOM tree — it moves from the clicked element up to its parent, then to its grandparent, all the way to document. Event delegation uses this natural bubbling.
User clicks <li>Task 1</li>
click fires on <li>
↓
click bubbles to <ul id="taskList"> ← Parent catches it here
↓
click bubbles to <body>
↓
click bubbles to <html>
↓
click bubbles to document
Syntax of Event Delegation — on() Method
$(parent).on(event, childSelector, function() {
// runs when the event fires on a matching child
});
Examples:
$("#menu").on("click", "a", function() { ... });
$("table").on("click", "td", function() { ... });
$(document).on("click", ".delete-btn", function() { ... });
Practical: Add and Delete Tasks
HTML:
<ul id="list"></ul>
<input id="newTask" type="text" placeholder="Task name" />
<button id="addTask">Add Task</button>
jQuery:
$(document).ready(function() {
// Add new task
$("#addTask").click(function() {
var task = $("#newTask").val();
if (task !== "") {
$("#list").append("<li>" + task + " <span class='del'>[Delete]</span></li>");
$("#newTask").val("");
}
});
// Delete using delegation (works for dynamically added items)
$("#list").on("click", ".del", function() {
$(this).parent().remove();
});
});
Each new task gets a delete button. Because we used delegation, the delete works for every task — even ones added after the page loaded.
Performance Benefit
Without delegation: if a table has 500 rows, jQuery attaches 500 separate click listeners — one per row. With delegation: jQuery attaches just 1 listener on the table. This saves memory and improves performance.
Without delegation: 500 rows × 1 listener each = 500 listeners With delegation: 1 listener on the table = 1 listener
When to Use Event Delegation
- Elements are added dynamically (AJAX results, user input).
- You have a large number of similar child elements (rows, cards, list items).
- You want to simplify your code by using one listener instead of many.
When Not to Use It
- For a single static element — direct binding is simpler.
- When event bubbling is stopped by another script using
stopPropagation().
Quick Summary
- Event delegation attaches a listener to a parent element instead of each child.
- It uses event bubbling — click events travel up the DOM tree automatically.
- Use
$(parent).on(event, childSelector, fn)syntax. - It works for dynamically added elements — the biggest advantage.
- It improves performance when many child elements share the same event.
