Event Bubbling in the DOM
Event bubbling is a concept that describes how events propagate or "bubble up" through the DOM tree. When an event occurs on…
Sometimes you need to attach event listeners to elements that don't exist when the page initially loads. This is common in scenarios like:
Traditional event binding doesn't work for these elements because they don't exist when the JavaScript runs on page load.
Event delegation solves this by attaching a single event listener to a parent element that exists when the page loads. This listener then handles events for all matching child elements, including those added later.
// Parent container
document.getElementById('modal-container').addEventListener('click', function(e) {
// Check if clicked element or its parent has the right class
if (e.target.closest('.edit-button')) {
e.preventDefault();
var itemId = e.target.closest('.edit-button').dataset.id;
console.log('Edit button clicked:', itemId);
openEditModal(itemId);
}
});
function openEditModal(itemId) {
var modal = document.createElement('div');
modal.className = 'modal';
modal.innerHTML = `
<h2>Edit Item ${itemId}</h2>
<input type="text" id="edit-field-${itemId}">
<button class="save-edit" data-id="${itemId}">Save</button>
`;
document.getElementById('modal-container').appendChild(modal);
}
// Event delegation for dynamically created modal content
document.getElementById('modal-container').addEventListener('click', function(e) {
if (e.target.matches('.save-edit')) {
var itemId = e.target.dataset.id;
var newValue = document.getElementById('edit-field-' + itemId).value;
console.log(`Saving item ${itemId} with new value: ${newValue}`);
// Save logic here
e.target.closest('.modal').remove();
}
});
modal-container, which exists on page load..closest() is used to check if the clicked element or any of its parents match the selector.// Parent container
$('#modal-container').on('click', '.edit-button', function(e) {
e.preventDefault();
var itemId = $(this).data('id');
console.log('Edit button clicked:', itemId);
openEditModal(itemId);
});
function openEditModal(itemId) {
var modal = $(`
<div class="modal">
<h2>Edit Item ${itemId}</h2>
<input type="text" id="edit-field-${itemId}">
<button class="save-edit" data-id="${itemId}">Save</button>
</div>
`);
$('#modal-container').append(modal);
}
// Event delegation for dynamically created modal content
$('#modal-container').on('click', '.save-edit', function() {
var itemId = $(this).data('id');
var newValue = $(`#edit-field-${itemId}`).val();
console.log(`Saving item ${itemId} with new value: ${newValue}`);
// Save logic here
$(this).closest('.modal').remove();
});
.on() method provides a more concise syntax for event delegation..on('click', '.edit-button', function() {...}) specifies the selector for target elements.Event delegation works because of event bubbling in the DOM. When an event occurs on an element:
By attaching the listener to a parent, we intercept the event as it bubbles up, checking if it originated from our target element.
Event delegation is a powerful technique for handling events on dynamic content. It simplifies your code, improves performance by reducing the number of event listeners, and ensures that your event handlers work for both existing and future elements.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com