addEventListener
addEventListener attaches an event handler to an element.
Basic Usage
const button = document.querySelector('button');
// Add click handler
button.addEventListener('click', () => {
console.log('Button clicked!');
});
// Named function (easier to remove)
function handleClick() {
console.log('Clicked!');
}
button.addEventListener('click', handleClick);
Event Types
// Mouse events
button.addEventListener('click', handler);
button.addEventListener('dblclick', handler);
button.addEventListener('mousedown', handler);
button.addEventListener('mouseup', handler);
button.addEventListener('mouseover', handler);
// Keyboard events
document.addEventListener('keydown', handler);
document.addEventListener('keyup', handler);
// Form events
form.addEventListener('submit', handler);
input.addEventListener('input', handler);
input.addEventListener('change', handler);
input.addEventListener('focus', handler);
input.addEventListener('blur', handler);
// Window events
window.addEventListener('resize', handler);
window.addEventListener('scroll', handler);
window.addEventListener('load', handler);
Adding Multiple Listeners
// Same event, multiple handlers
button.addEventListener('click', firstHandler);
button.addEventListener('click', secondHandler);
// Both will execute
button.addEventListener('mousedown', handler1);
button.addEventListener('mouseup', handler2);
Options Object
button.addEventListener('click', handler, {
capture: false, // Listen in capturing phase
once: true, // Remove after first call
passive: true, // Never calls preventDefault()
signal: abortController.signal // AbortController
});
// once: true - auto-remove after first call
button.addEventListener('click', () => {
console.log('This runs only once');
}, { once: true });
// passive: true - for performance (scroll, touch events)
document.addEventListener('touchmove', handler, { passive: true });
Arrow Functions vs Named Functions
// Arrow function - can't remove (no reference)
button.addEventListener('click', () => {
console.log('clicked');
});
// Named function - can remove
function handleClick() {
console.log('clicked');
}
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick);
removeEventListener
removeEventListener removes an event handler. Must pass the same function reference.
Basic Usage
function handleClick() {
console.log('clicked');
}
// Add
button.addEventListener('click', handleClick);
// Remove (must pass same function reference)
button.removeEventListener('click', handleClick);
Common Mistake
// WRONG - anonymous function can't be removed
button.addEventListener('click', () => {
console.log('clicked');
});
button.removeEventListener('click', () => {
console.log('clicked');
}); // Doesn't work! Different function!
// CORRECT - use named function
function handleClick() {
console.log('clicked');
}
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick); // Works!
Cleanup Pattern
function setup() {
const handler = (e) => console.log(e.target);
button.addEventListener('click', handler);
// Return cleanup function
return () => {
button.removeEventListener('click', handler);
};
}
const cleanup = setup();
// Later:
cleanup(); // Removes listener
AbortController Pattern
const controller = new AbortController();
button.addEventListener('click', handler, {
signal: controller.signal
});
// Remove all listeners with this signal
controller.abort();
// Can also abort after timeout
setTimeout(() => controller.abort(), 5000);
Event Listener Cleanup in Components
// React-like cleanup
useEffect(() => {
const handler = () => { /* ... */ };
window.addEventListener('resize', handler);
return () => {
window.removeEventListener('resize', handler);
};
}, []);
// Class component
class Component {
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
}
Event Object
The event object contains information about the event.
Event Object Properties
button.addEventListener('click', (event) => {
// Basic properties
console.log(event.type); // 'click'
console.log(event.target); // Element that triggered event
console.log(event.currentTarget); // Element with listener
console.log(event.timeStamp); // When event occurred
// Mouse properties
console.log(event.clientX); // X position
console.log(event.clientY); // Y position
console.log(event.pageX); // X relative to document
console.log(event.pageY); // Y relative to document
// Keyboard properties
console.log(event.key); // 'Enter', 'a', etc.
console.log(event.code); // 'KeyA', 'Enter'
console.log(event.altKey); // Alt held
console.log(event.ctrlKey); // Ctrl held
console.log(event.shiftKey); // Shift held
// Form properties
console.log(event.target.value);
console.log(event.target.checked);
});
Preventing Default Behavior
// Prevent form submission
form.addEventListener('submit', (e) => {
e.preventDefault(); // Form won't submit
// Handle with JavaScript
});
// Prevent link navigation
link.addEventListener('click', (e) => {
e.preventDefault(); // Won't navigate
});
// Prevent context menu
document.addEventListener('contextmenu', (e) => {
e.preventDefault(); // No right-click menu
});
Stopping Propagation
// Stop bubbling
document.addEventListener('click', (e) => {
if (e.target.closest('.modal')) {
e.stopPropagation(); // Won't bubble to document
}
});
// Stop immediate propagation
button.addEventListener('click', (e) => {
e.stopImmediatePropagation(); // Other listeners won't fire
console.log('First handler');
});
button.addEventListener('click', () => {
console.log('Second handler'); // Won't run
});
Event Delegation with Event Object
const list = document.querySelector('ul');
list.addEventListener('click', (e) => {
// Find the list item
const item = e.target.closest('li');
// Check if click was on a list item
if (item && list.contains(item)) {
// Get item data
const id = item.dataset.id;
const text = item.textContent;
// Handle click
handleItemClick(id, text);
}
});
Practice Problems
Create a reusable React component implementing Event Listeners. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Event Listeners using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Event Listeners for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. Why can't you remove an anonymous event listener?
2. What does e.preventDefault() do?
3. What is the difference between target and currentTarget?
4. What does the { once: true } option do?
Flashcards
Question
How to add an event listener?
Click to reveal answer
Answer
element.addEventListener('event', handler, options) - options include capture, once, passive, signal.
Question
How to remove an event listener?
Click to reveal answer
Answer
element.removeEventListener('event', handler) - must pass the same function reference used in addEventListener.
Question
What is e.target vs e.currentTarget?
Click to reveal answer
Answer
target: element that triggered the event. currentTarget: element with the listener attached.
Question
What does preventDefault() do?
Click to reveal answer
Answer
Prevents the browser's default action (form submit, link navigation) but doesn't stop propagation.
Question
What is Event Listeners?
Click to reveal answer
Answer
Event Listeners is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.addEventListener is the standard way to handle events
- 2.You need the same function reference to remove listeners
- 3.e.target is the clicked element, e.currentTarget has the listener
- 4.preventDefault() stops browser default behavior
- 5.Use { once: true } for one-time handlers
Interview Tips
- •Show how to properly add and remove event listeners
- •Explain the difference between target and currentTarget
- •Demonstrate event delegation patterns
- •Discuss when to use { passive: true } for performance
Cheat Sheet
Event Listeners Cheat Sheet
Adding Listeners
el.addEventListener('click', handler, options);
Options
capture: Listen in capturing phaseonce: Remove after first callpassive: Can't call preventDefault()signal: AbortController signal
Removing Listeners
el.removeEventListener('click', handler);
Event Object
e.target: Triggered elemente.currentTarget: Listener elemente.preventDefault(): Stop default behaviore.stopPropagation(): Stop bubbling