Module 33 : Event Delegation.
🧠 What is Event Delegation?
Event Delegation is a technique where you add a single event listener to a parent element instead of individual child elements. This takes advantage of event bubbling—a process in which events propagate (bubble up) from the target element up through the DOM tree.
📌 Why Use Event Delegation?
Advantage
Explanation
Performance
Fewer listeners mean less memory usage and better performance.
Dynamic Elements
Works for elements added later (e.g., via JavaScript or AJAX).
Cleaner Code
Reduces redundancy and makes code easier to maintain.
🔁 How Events Work in JavaScript (Bubbling vs Capturing)
🔼 Bubbling Phase (used in Event Delegation)
An event starts from the target element and bubbles up through its ancestors.
html code
<div id="parent"> <button id="child">Click Me</button> </div>
js code
document.getElementById('parent').addEventListener('click', function(event) { console.log('Parent clicked'); });
When #child is clicked, the event bubbles to #parent, triggering the handler.
Example: Without Delegation
html code
<ul id="menu"> <li>Home</li> <li>About</li> <li>Contact</li> </ul>
js code
document.querySelectorAll('#menu li').forEach(item => { item.addEventListener('click', () => { alert('Item clicked: ' + item.textContent); }); });
🚫 Problem: If you dynamically add a new <li>, it won’t work unless you re-bind.
✅ Example: With Event Delegation
js code
document.getElementById('menu').addEventListener('click', function(event) { if (event.target.tagName === 'LI') { alert('Delegated: ' + event.target.textContent); } });
✔️ Now even dynamically added <li> elements will be handled!
Method: Implementing Event Delegation (Step-by-Step)
Select a common parent element
Attach a single event listener to that parent
Use event.target to determine which child was clicked
Optionally filter using tagName, classList, or matches()
js code
parentElement.addEventListener('click', function(event) { if (event.target.matches('.child-class')) { // Handle event } });
Experiment 1: Delegated Button Clicks
Objective:
Implement delegated events to handle clicks on buttons inside a container.
HTML:
html code
<div id="button-container"> <button class="btn">Button 1</button> <button class="btn">Button 2</button> </div>
JavaScript:
js code
document.getElementById('button-container').addEventListener('click', function(e) { if (e.target.classList.contains('btn')) { console.log('You clicked: ' + e.target.textContent); } });
✅ Outcome:
Clicking any button logs its text. Works even if buttons are dynamically added later.
Experiment 2: Dynamic List Interaction
💡 Objective:
Create a list where items can be added dynamically, and clicks are delegated.
HTML:
html code
<ul id="task-list"> <li>Task 1</li> <li>Task 2</li> </ul> <input type="text" id="new-task" placeholder="Add Task" /> <button id="add-task">Add</button>
JavaScript:
js code
document.getElementById('add-task').addEventListener('click', () => { const task = document.getElementById('new-task').value; if (task) { const li = document.createElement('li'); li.textContent = task; document.getElementById('task-list').appendChild(li); } }); document.getElementById('task-list').addEventListener('click', function(e) { if (e.target.tagName === 'LI') { alert('Task selected: ' + e.target.textContent); } });
✅ Result:
Clicking any list item shows an alert, even if it was added dynamically.
Exercise
Implement a delegated event handler that allows users to remove list items by clicking on them.
Hint:
Use e.target.remove() inside the event listener.
📖 Advanced: Using closest() for Nested Structures
js code
container.addEventListener('click', function(e) { const card = e.target.closest('.card'); if (card) { console.log('Card clicked:', card.dataset.id); } });
✅ closest() traverses ancestors, useful in complex nested HTML.
📚 Research Insights
🔬 How Browsers Handle Delegation:
Event delegation uses the bubbling phase.
Browsers optimize event handling internally using shared memory references for listeners.
Delegation avoids re-attaching listeners after DOM updates (great for frameworks like React, Angular).
🔍 Case Study:
old DOM-based chat app used delegation heavily to manage thousands of chat buttons efficiently without memory leaks.
🧠 Summary
Concept
Summary
Event Delegation
A technique to manage events using a parent element
Event Bubbling
Events bubble from the target to ancestors
Benefits
Better performance, dynamic support, cleaner code
Best Practices
Use filtering (tagName, classList, matches), clean logic
Browser Support
Fully supported in all major browsers
📋 Checklist for Implementation
✅ Use a parent element
✅ Attach a single event listener
✅ Use event.target or closest()
✅ Filter target by tag/class
✅ Test dynamic behavior
🎓 (Self-Check)
What phase of the event flow does delegation rely on?
What method can be used to determine if the clicked element matches a specific selector?
What’s the main advantage of using event delegation?
(Answers at the end of your exercise sheet)
Additional : Event Delegation for Table Rows
ID
Name
Action
1
John
Delete
2
Jane
Delete
Clicking "Delete" should remove the row.
JavaScript:
js code
document.querySelector('table').addEventListener('click', function(e) { if (e.target.classList.contains('delete')) { e.target.closest('tr').remove(); } });
📁 Assignment
Build a dynamic FAQ section:
A parent container holds FAQ entries.
Each entry has a question and a hidden answer.
Clicking the question should toggle the answer.
Use event delegation to handle the toggle.
✅ Final Thoughts
Event Delegation is a critical concept in building scalable, efficient front-end applications. It aligns perfectly with modern dynamic UIs and promotes clean, memory-efficient JavaScript.
No comments:
Post a Comment