Events
- Browser notifications of user interactions and state changes
- Foundation of interactive web applications
- Event-driven programming model
Key Insight
Events are the browser’s way of saying “something happened”\u2014not just clicks, but scrolls, hovers, form submissions, page loads, network responses, animations completing, and hundreds of other moments your code can react to. The event system transforms the browser from a static document viewer into an interactive application platform. Understanding event propagation (bubbling/capturing), delegation, and preventDefault is what separates developers who can “make buttons work” from those who can build sophisticated, performant UIs with proper keyboard navigation, form validation, and infinite scroll.
Detailed Description
Events are fired to notify code of “interesting changes” that may affect code execution. These can arise from user interactions such as using a mouse or resizing a window, changes in the state of the underlying environment (e.g. low battery or media events from the operating system), and other causes.
The browser’s event system is based on the observer pattern: you register listeners for specific event types, and when those events occur, your callback functions execute. Events follow a propagation path through the DOM tree, enabling powerful patterns like event delegation. The Event object passed to handlers contains rich information about what happened (which key, mouse position, target element, etc.)
Key characteristics of events:
- Event types - Click, keydown, submit, load, scroll, etc. (100+ types)
- Event propagation - Events flow through DOM (capturing → target → bubbling)
- Event object - Contains information about the event (target, type, timestamp)
- Default behaviors - Many events have browser default actions (links navigate, forms submit)
- Custom events - You can create and dispatch your own events
Code Examples
Basic Example: Event Listeners and Handlers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript Event Example</title>
</head>
<body>
<button id="myButton">Click me</button>
<input type="text" id="myInput" placeholder="Type something..." />
<script>
// Click event
const button = document.getElementById("myButton");
function handleClick(event) {
console.log('Button clicked!');
console.log('Event type:', event.type);
console.log('Target element:', event.target);
console.log('Timestamp:', event.timeStamp);
}
button.addEventListener("click", handleClick);
// Keyboard events
const input = document.getElementById("myInput");
input.addEventListener("keydown", (event) => {
console.log('Key pressed:', event.key);
console.log('Key code:', event.code);
// Detect special keys
if (event.key === 'Enter') {
console.log('Enter key pressed!');
}
if (event.ctrlKey && event.key === 's') {
event.preventDefault(); // Prevent browser save dialog
console.log('Ctrl+S pressed - custom save action');
}
});
// Input event (fires on every change)
input.addEventListener("input", (event) => {
console.log('Current value:', event.target.value);
});
// Focus and blur events
input.addEventListener("focus", () => {
console.log('Input focused');
input.style.borderColor = 'blue';
});
input.addEventListener("blur", () => {
console.log('Input lost focus');
input.style.borderColor = '';
});
</script>
</body>
</html>
Practical Example: Event Propagation and Delegation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Propagation Example</title>
<style>
.outer { padding: 20px; background: lightblue; }
.middle { padding: 20px; background: lightgreen; margin: 10px; }
.inner { padding: 20px; background: lightcoral; margin: 10px; }
</style>
</head>
<body>
<div class="outer" id="outer">
Outer
<div class="middle" id="middle">
Middle
<div class="inner" id="inner">
Inner (Click me!)
</div>
</div>
</div>
<script>
const outer = document.getElementById('outer');
const middle = document.getElementById('middle');
const inner = document.getElementById('inner');
// Event bubbling (default)
outer.addEventListener('click', (e) => {
console.log('Outer clicked (bubbling)');
});
middle.addEventListener('click', (e) => {
console.log('Middle clicked (bubbling)');
// Stop propagation to prevent outer from receiving event
// e.stopPropagation();
});
inner.addEventListener('click', (e) => {
console.log('Inner clicked (bubbling)');
console.log('Event target:', e.target);
console.log('Current target:', e.currentTarget);
});
// Event capturing (runs before bubbling)
outer.addEventListener('click', (e) => {
console.log('Outer clicked (capturing)');
}, true); // Third parameter = useCapture
// Click on inner element outputs:
// Outer clicked (capturing) ← Capturing phase (top to bottom)
// Inner clicked (bubbling) ← Target phase
// Middle clicked (bubbling) ← Bubbling phase (bottom to top)
// Outer clicked (bubbling)
</script>
<!-- Event Delegation Example -->
<ul id="todoList">
<li data-id="1">Task 1 <button class="delete">Delete</button></li>
<li data-id="2">Task 2 <button class="delete">Delete</button></li>
<li data-id="3">Task 3 <button class="delete">Delete</button></li>
</ul>
<script>
// Event delegation - one listener for all buttons
const todoList = document.getElementById('todoList');
todoList.addEventListener('click', (event) => {
// Check if delete button was clicked
if (event.target.matches('button.delete')) {
const listItem = event.target.closest('li');
const taskId = listItem.dataset.id;
console.log(`Deleting task ${taskId}`);
listItem.remove();
}
});
// Adding new items dynamically (no need to add listeners)
const newTask = document.createElement('li');
newTask.dataset.id = '4';
newTask.innerHTML = 'Task 4 <button class="delete">Delete</button>';
todoList.appendChild(newTask);
// Delete button automatically works via delegation!
</script>
</body>
</html>
Advanced Example: Custom Events and Event Patterns
// Custom events
class EventBus {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
off(eventName, callback) {
if (!this.events[eventName]) return;
this.events[eventName] = this.events[eventName].filter(
cb => cb !== callback
);
}
emit(eventName, data) {
if (!this.events[eventName]) return;
this.events[eventName].forEach(callback => {
callback(data);
});
}
}
// Usage
const eventBus = new EventBus();
eventBus.on('userLoggedIn', (user) => {
console.log('User logged in:', user.name);
});
eventBus.on('userLoggedIn', (user) => {
console.log('Welcome notification sent to', user.email);
});
eventBus.emit('userLoggedIn', { name: 'Alice', email: 'alice@example.com' });
// Native CustomEvent
const button = document.getElementById('customButton');
// Dispatch custom event
const customEvent = new CustomEvent('myCustomEvent', {
detail: { message: 'Hello from custom event!', timestamp: Date.now() },
bubbles: true,
cancelable: true
});
button.dispatchEvent(customEvent);
// Listen for custom event
button.addEventListener('myCustomEvent', (event) => {
console.log('Custom event received:', event.detail);
});
// Debouncing events
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
// Usage: Debounce scroll event
const handleScroll = debounce(() => {
console.log('Scrolled!', window.scrollY);
}, 300);
window.addEventListener('scroll', handleScroll);
// Throttling events
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// Usage: Throttle mousemove
const handleMouseMove = throttle((event) => {
console.log('Mouse position:', event.clientX, event.clientY);
}, 100);
document.addEventListener('mousemove', handleMouseMove);
// Passive event listeners for scroll performance
document.addEventListener('scroll', handleScroll, {
passive: true // Tells browser we won't call preventDefault()
});
// Once option - listener automatically removed after first trigger
button.addEventListener('click', () => {
console.log('This runs only once');
}, { once: true });
// Form validation with events
const form = document.getElementById('myForm');
const emailInput = document.getElementById('email');
emailInput.addEventListener('blur', (event) => {
const email = event.target.value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
event.target.setCustomValidity('Invalid email address');
event.target.reportValidity();
} else {
event.target.setCustomValidity('');
}
});
form.addEventListener('submit', (event) => {
event.preventDefault(); // Prevent default form submission
const formData = new FormData(event.target);
const data = Object.fromEntries(formData);
console.log('Form data:', data);
// Send data via fetch
fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => console.log('Success:', result))
.catch(error => console.error('Error:', error));
});
Common Mistakes
1. Not Removing Event Listeners (Memory Leaks)
Mistake: Adding listeners without cleanup causes memory leaks.
// ❌ BAD: Memory leak in SPA
function setupComponent() {
const button = document.getElementById('button');
button.addEventListener('click', () => {
console.log('Clicked');
});
// Component unmounts but listener remains
}
// Called multiple times in SPA
setupComponent(); // Leak
setupComponent(); // Another leak
setupComponent(); // More leaks...
// ✅ GOOD: Clean up listeners
function setupComponent() {
const button = document.getElementById('button');
function handleClick() {
console.log('Clicked');
}
button.addEventListener('click', handleClick);
// Return cleanup function
return () => {
button.removeEventListener('click', handleClick);
};
}
const cleanup = setupComponent();
// Later, when component unmounts
cleanup();
// Or use AbortController (modern)
const controller = new AbortController();
button.addEventListener('click', handleClick, {
signal: controller.signal
});
// Clean up all listeners at once
controller.abort();
Why it matters: In SPAs, listeners accumulate without cleanup, causing memory leaks and duplicate event handling.
2. Using addEventListener Inside Loops Without Delegation
Mistake: Attaching individual listeners to many elements.
// ❌ BAD: 1000 event listeners
const items = document.querySelectorAll('.item'); // 1000 items
items.forEach(item => {
item.addEventListener('click', handleClick); // 1000 listeners!
});
// Memory intensive, slow performance
// ✅ GOOD: Event delegation (1 listener)
const container = document.getElementById('container');
container.addEventListener('click', (event) => {
if (event.target.matches('.item')) {
handleClick(event.target);
}
});
// Single listener handles all items
Why it matters: 1000 listeners use 1000x more memory than delegation. Delegation also handles dynamically added elements automatically.
3. Forgetting preventDefault() on Form Submit
Mistake: Form submits causing page refresh.
// ❌ BAD: Page refreshes
const form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
const data = new FormData(event.target);
console.log('Data:', Object.fromEntries(data));
// Page refreshes here! Data not sent via AJAX
});
// ✅ GOOD: Prevent default submit
form.addEventListener('submit', (event) => {
event.preventDefault(); // Stop page refresh
const data = new FormData(event.target);
fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(data))
});
});
Why it matters: Without preventDefault(), forms trigger browser’s default submit behavior (page refresh), breaking SPA user experience.
Quick Quiz
Question 1: What's the difference between event bubbling and capturing?
**Answer:** **Bubbling goes from target → root; capturing goes root → target:** ```htmlQuestion 2: When should you use event delegation?
**Answer:** **Use delegation for lists, dynamic content, and performance optimization:** **When to use delegation:** ```javascript // ✅ Large lists (100+ items) const list = document.getElementById('productList'); list.addEventListener('click', (e) => { if (e.target.matches('.buy-button')) { const productId = e.target.dataset.productId; buyProduct(productId); } }); // One listener handles all 1000 product buttons // ✅ Dynamic content (items added/removed) const chat = document.getElementById('chatMessages'); chat.addEventListener('click', (e) => { if (e.target.matches('.delete-message')) { e.target.closest('.message').remove(); } }); // New messages automatically work without adding listeners // ✅ Multiple event types on container container.addEventListener('click', (e) => { if (e.target.matches('.edit-btn')) handleEdit(e.target); if (e.target.matches('.delete-btn')) handleDelete(e.target); if (e.target.matches('.share-btn')) handleShare(e.target); }); ``` **When NOT to use delegation:** ```javascript // ❌ Single element (no benefit) const singleButton = document.getElementById('uniqueButton'); singleButton.addEventListener('click', handleClick); // Direct listener is fine // ❌ Events that don't bubble (focus, blur, scroll on elements) input.addEventListener('focus', handleFocus); // Can't delegate focus // ❌ Need precise element reference const specificDiv = document.getElementById('specificDiv'); specificDiv.addEventListener('click', function() { this.classList.toggle('active'); // 'this' is the specific element }); ``` **Why it matters:** Delegation improves performance (fewer listeners), handles dynamic content automatically, and reduces memory usage.Question 3: What's the difference between stopPropagation() and preventDefault()?
**Answer:** **stopPropagation() stops event flow; preventDefault() stops default browser action:** **stopPropagation() - Stops event bubbling/capturing:** ```htmlQuestion 4: How do you debounce and throttle event handlers?
**Answer:** **Debounce delays execution until events stop; throttle limits execution rate:** **Debounce - Wait for pause:** ```javascript function debounce(func, delay) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; } // Usage: Search input const searchInput = document.getElementById('search'); const handleSearch = debounce((event) => { const query = event.target.value; console.log('Searching for:', query); // API call here }, 300); searchInput.addEventListener('input', handleSearch); // User types "hello": // h (start timer) // he (cancel timer, start new) // hel (cancel timer, start new) // hell (cancel timer, start new) // hello (cancel timer, start new) // ... 300ms pause ... // "Searching for: hello" (executes once) ``` **Throttle - Limit execution rate:** ```javascript function throttle(func, limit) { let inThrottle; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } // Usage: Scroll event const handleScroll = throttle(() => { console.log('Scroll position:', window.scrollY); // Update UI based on scroll }, 100); window.addEventListener('scroll', handleScroll); // User scrolls continuously: // t=0ms: Executes (set throttle) // t=20ms: Ignored (in throttle) // t=50ms: Ignored (in throttle) // t=100ms: Throttle released // t=105ms: Executes (set throttle again) // t=150ms: Ignored // ... ``` **When to use each:** | Use Case | Pattern | Why | |----------|---------|-----| | Search input | Debounce | Wait for user to stop typing | | Window resize | Debounce | Wait for resize to finish | | Scroll updates | Throttle | Update UI at regular intervals | | Mousemove tracking | Throttle | Limit high-frequency events | | Auto-save | Debounce | Save after user stops editing | | Button click spam | Throttle | Prevent rapid re-clicking | **Using Lodash (production-ready):** ```javascript import { debounce, throttle } from 'lodash'; const debouncedSearch = debounce(handleSearch, 300); const throttledScroll = throttle(handleScroll, 100); ``` **Why it matters:** Debounce/throttle prevent performance issues from high-frequency events (scroll, resize, input), reducing API calls and UI updates.Question 5: What are passive event listeners and when should you use them?
**Answer:** **Passive listeners promise not to call preventDefault(), enabling browser scroll optimizations:** **Without passive (default):** ```javascript // Browser must wait to see if preventDefault() is called document.addEventListener('touchstart', (e) => { console.log('Touch started'); // Browser blocks scrolling until this function completes // (in case preventDefault() is called) }, false); ``` **With passive:** ```javascript // Tell browser we won't call preventDefault() document.addEventListener('touchstart', (e) => { console.log('Touch started'); // Browser can scroll immediately without waiting }, { passive: true }); // If you try to call preventDefault() with passive document.addEventListener('touchstart', (e) => { e.preventDefault(); // ⚠️ Ignored! Console warning }, { passive: true }); ``` **When to use passive:** ```javascript // ✅ Scroll listeners (tracking only, not preventing) window.addEventListener('scroll', handleScroll, { passive: true }); // ✅ Touch events (tracking gestures, not preventing scroll) element.addEventListener('touchmove', trackSwipe, { passive: true }); // ✅ Wheel events (analytics, not preventing scroll) document.addEventListener('wheel', trackWheelEvents, { passive: true }); // ❌ Don't use passive when you need preventDefault() document.addEventListener('touchmove', (e) => { if (shouldPrevent) { e.preventDefault(); // Need this to work } }, { passive: false }); // Must be false (or omit) ``` **Performance impact:** ```javascript // Passive listener performance test const passiveSupported = (() => { let supported = false; try { const options = { get passive() { supported = true; return false; } }; window.addEventListener('test', null, options); window.removeEventListener('test', null, options); } catch(err) { supported = false; } return supported; })(); if (passiveSupported) { window.addEventListener('scroll', onScroll, { passive: true }); } else { window.addEventListener('scroll', onScroll); } ``` **Scroll performance comparison:** ```javascript // ❌ Non-passive (blocks scrolling) document.addEventListener('touchstart', (e) => { console.log('Touch'); // Browser waits 16ms to check for preventDefault() // Scroll janky at 60fps }); // ✅ Passive (smooth scrolling) document.addEventListener('touchstart', (e) => { console.log('Touch'); // Browser scrolls immediately // Smooth 60fps }, { passive: true }); ``` **Why it matters:** Passive listeners enable smooth scrolling on mobile (60fps) by allowing browser to scroll immediately without waiting for JavaScript. Critical for scroll performance.Types of HTML Element Events
Common Categories of HTML Element Events
| Event Category | Description | Example Events |
|---|---|---|
| Mouse Events | Triggered by mouse actions | click, mouseover, mouseout, mousedown, mouseup, dblclick |
| Keyboard Events | Triggered by keyboard actions | keydown, keyup, keypress |
| Form Events | Related to form input and submission | submit, change, input, focus, blur, reset |
| Drag & Drop Events | Involved in drag-and-drop operations | drag, dragstart, dragend, dragenter, dragleave, dragover, drop |
| Clipboard Events | Triggered by cut, copy, and paste actions | copy, cut, paste |
| Media Events | Related to media elements like audio and video | play, pause, ended, volumechange, timeupdate |
| Focus Events | Occur when elements gain or lose focus | focus, blur, focusin, focusout |
| Load/Unload Events | Related to loading/unloading of documents or resources | load, unload, beforeunload |
| Touch Events | Triggered by touch interactions (mobile devices) | touchstart, touchend, touchmove, touchcancel |
| Wheel/Scroll Events | Triggered by scrolling or mouse wheel actions | scroll, wheel |
| Animation/Transition | Related to CSS animations and transitions | animationstart, animationend, transitionend |
| Input Events | Triggered by changes to input fields | input, change |
References
- MDN: Introduction to Events
- MDN: Event Reference ```
- Drag & Drop Events:
<div ondrop="dropHandler(event)" ondragover="allowDrop(event)"></div>
How to Attach Event Handlers
- Inline HTML Attributes:
Use attributes likeonclick,onchange, etc., directly in HTML[5]. - DOM Properties:
Assign a function to an element’s event property, e.g.,element.onclick = handler;[3][5]. - addEventListener Method:
Attach multiple event handlers or listen for events dynamically:element.addEventListener('click', handler);This method is recommended for flexibility and scalability[3][7].
Comprehensive References
These sources provide exhaustive lists and documentation for all standard HTML events.
Framework transformation of events
HTML events are handled differently in modern frameworks and libraries to provide enhanced developer experience, maintainability, and integration with their component models. Here’s how each major technology transforms and manages HTML element events:
React
- Event Syntax: Uses camelCase for event names (e.g.,
onClickinstead ofonclick). - Handler Assignment: Event handlers are passed as functions inside curly braces, e.g.,
<button onClick={handleClick}>. - Synthetic Events: React wraps native events in a SyntheticEvent system for cross-browser consistency.
- Passing Arguments: To pass arguments, use an arrow function:
<button onClick={() => handleClick(arg)}>[1][5]. - Event Object: The event handler receives a synthetic event object, which closely mimics the native event but is normalized across browsers[1][5].
Angular
- Event Binding Syntax: Uses parentheses around the event name, e.g.,
<button (click)="doSomething()">. - Template Statements: The handler is usually a method or expression in the component class.
- Event Object Access: The special
$eventvariable provides access to the native event object, e.g.,<input (keyup)="onKey($event)">[2][6]. - Event Modifiers: Angular supports key and code modifiers for keyboard events, such as
(keyup.enter)to only trigger on Enter key, or combinations like(keyup.shift.enter)[2]. - Legacy AngularJS: Uses directives like
ng-click,ng-mouseover, etc., but the core concepts remain similar[6].
Vue
- Event Directive: Uses the
v-ondirective or its shorthand@, e.g.,<button v-on:click="doSomething">or<button @click="doSomething">. - Handler Types: Can use inline expressions or reference methods defined in the component.
- Event Modifiers: Vue provides modifiers like
.stop,.prevent,.once,.capture, and key modifiers for more granular control, e.g.,@submit.prevent="onSubmit"[3][7]. - Automatic Reactivity: When an event changes reactive data, the UI automatically updates[3][7].
Web Components
- Native Event Handling: Use standard DOM methods like
addEventListenerdirectly on elements or within the component’s shadow DOM[8][10]. - Custom Events: Web components often define and dispatch custom events using the
CustomEventconstructor anddispatchEvent, enabling communication with parent components or the broader application[8][9]. - Event Delegation: Common for optimizing performance, especially with dynamic lists—attach a single listener to a parent and handle events as they bubble up[8].
- Cleanup: Event listeners should be removed in lifecycle callbacks (e.g.,
disconnectedCallback) to avoid memory leaks[10]. - Advanced Patterns: The
handleEvent()method can be used for cleaner event handler management in custom elements[10].
Comparison Table
| Framework/Library | Event Syntax Example | Handler Binding | Event Object | Modifiers/Features |
|---|---|---|---|---|
| React | <button onClick={fn}> |
Function in JSX | SyntheticEvent | Arrow functions for args, preventDefault, stopPropagation |
| Angular | <button (click)="fn()"> |
Method in component | $event (native) |
Key/code modifiers, template expressions |
| Vue | <button @click="fn"> |
Method or inline | Native event | .stop, .prevent, .once, key modifiers |
| Web Components | addEventListener('click', fn) |
Direct DOM binding | Native event | Custom events, event delegation, cleanup in lifecycle |
Summary
HTML elements support a rich set of event types, including mouse, keyboard, form, media, drag-and-drop, clipboard, and more. Developers can attach event handlers using inline attributes, DOM properties, or the addEventListener method for robust and interactive web applications[1][2][3][5][6].
- React transforms HTML events into camelCase props and uses a synthetic event system for consistency.
- Angular binds events using parentheses and provides powerful modifiers and access to the native event object.
- Vue uses the
v-ondirective (or@shorthand) with modifiers for expressive event handling and reactivity. - Web Components leverage standard DOM event APIs, with additional patterns for custom events and lifecycle management.
Each approach reflects the framework’s philosophy: React and Vue integrate events tightly with their component models, Angular provides declarative and expressive syntax with modifiers, and Web Components rely on native browser APIs for maximum flexibility and interoperability.
References
- https://developer.mozilla.org/en-US/docs/Web/Events
- [1] https://www.w3schools.com/tags/ref_eventattributes.asp
- [2] https://developer.mozilla.org/en-US/docs/Web/Events
- [3] https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Events
- [4] https://html.spec.whatwg.org/dev/webappapis.html
- [5] https://www.w3schools.com/js/js_htmldom_events.asp
- [6] https://education.launchcode.org/intro-to-web-dev-curriculum/dom-and-events/reading/event-types/index.html
- [7] https://www.w3schools.com/js/js_htmldom_eventlistener.asp
- [8] https://stackoverflow.com/questions/59406682/is-there-any-event-type-for-html-element-in-typescript
- [9] https://stackoverflow.com/questions/53356911/where-can-i-find-a-list-of-possible-events-for-an-html-element
- [1] https://www.w3schools.com/react/react_events.asp
- [2] https://angular.dev/guide/templates/event-listeners
- [3] https://www.w3schools.com/vue/vue_events.php
- [4] https://open-wc.org/guides/knowledge/events/
- [5] https://withcodeexample.com/react-event-handling-guide/
- [6] https://www.w3schools.com/angular/angular_events.asp
- [7] https://vuejs.org/guide/essentials/event-handling
- [8] https://blog.pixelfreestudio.com/how-to-use-event-handling-in-web-components/
- [9] https://javascript.plainenglish.io/custom-event-handling-101-a-guide-to-web-component-communication-184bf115a81d
- [10] https://ryanmulligan.dev/blog/handling-events-web-components/
- [11] https://legacy.reactjs.org/docs/handling-events.html
- [12] https://react.dev/learn/responding-to-events
- [13] https://legacy.reactjs.org/docs/events.html
- [14] https://www.shecodes.io/athena/39543-understanding-the-event-target-property-in-react
- [15] https://stackoverflow.com/questions/60998463/react-dynamically-add-html-element-with-event-handler
- [16] https://angular.love/optimizing-events-handling-in-angular
- [17] https://v2.vuejs.org/v2/guide/events
- [18] https://stackoverflow.com/questions/73055022/how-to-handle-event-on-html-render-by-computed-function-in-vue-js
- [19] https://vuejs.org/guide/components/events
- [20] https://stackoverflow.com/questions/43061417/how-to-listen-for-custom-events-defined-web-component
- [21] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements
- [22] https://developer.mozilla.org/en-US/docs/Web/API/Web_components
- [23] https://www.reddit.com/r/elm/comments/18j3iao/how_to_create_and_use_a_custom_web_component_with/
- [24] https://www.freecodecamp.org/news/how-to-handle-events-in-react-19/
- [25] https://stackoverflow.com/questions/56827863/is-there-a-way-to-attach-reactjs-events-to-dynamically-inserted-html-from-ajax-j
- [26] https://www.geeksforgeeks.org/react-js-events/
- [27] https://v17.angular.io/guide/event-binding
- [28] https://stackoverflow.com/questions/59482603/how-to-grab-an-html-element-within-my-angular-component-and-apply-an-event-liste
- [29] https://angular.dev/tutorials/learn-angular/7-event-handling
- [30] https://docs.angular.lat/guide/event-binding
- [31] https://v17.angular.io/guide/event-binding-concepts
- [32] https://30dayscoding.com/blog/handling-events-and-event-handling-patterns-in-vuejs
- [33] https://www.geeksforgeeks.org/vue-js-event-handling/
- [34] https://www.freecodecamp.org/news/how-event-handling-works-in-vue-3-guide-for-devs/
- [35] https://stackoverflow.com/questions/47435724/adding-events-to-dynamically-rendered-html-in-vue-js-component
- [36] https://www.reddit.com/r/vuejs/comments/gn3ki0/vhtml_and_emitting_events/