// Basic event listener
const button = document.getElementById('myButton');
button.addEventListener('click', function(event) {
console.log('Button clicked!');
console.log('Event type:', event.type);
console.log('Target:', event.target);
});
// Arrow function syntax
button.addEventListener('click', (e) => {
console.log('Clicked with arrow function');
});
// Named function (removable)
function handleClick(event) {
console.log('Handling click');
}
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick);
// Event object properties
document.addEventListener('click', (event) => {
console.log('Type:', event.type);
console.log('Target:', event.target);
console.log('CurrentTarget:', event.currentTarget);
console.log('Timestamp:', event.timeStamp);
console.log('ClientX:', event.clientX);
console.log('ClientY:', event.clientY);
});
// Prevent default behavior
const link = document.querySelector('a');
link.addEventListener('click', (event) => {
event.preventDefault();
console.log('Link clicked but navigation prevented');
});
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
console.log('Form submitted but page refresh prevented');
const formData = new FormData(event.target);
console.log(Object.fromEntries(formData));
});
// Stop propagation
const parent = document.getElementById('parent');
const child = document.getElementById('child');
parent.addEventListener('click', () => {
console.log('Parent clicked');
});
child.addEventListener('click', (event) => {
console.log('Child clicked');
event.stopPropagation(); // Parent handler won't run
});
// Event delegation pattern
const list = document.getElementById('todoList');
// Instead of attaching to each item:
list.addEventListener('click', (event) => {
// Filter by target element
if (event.target.matches('.delete-btn')) {
const todoItem = event.target.closest('.todo-item');
todoItem.remove();
}
if (event.target.matches('.edit-btn')) {
const todoItem = event.target.closest('.todo-item');
editTodo(todoItem);
}
if (event.target.matches('.complete-checkbox')) {
const todoItem = event.target.closest('.todo-item');
todoItem.classList.toggle('completed');
}
});
// Keyboard events
const input = document.getElementById('searchInput');
input.addEventListener('keydown', (event) => {
console.log('Key:', event.key);
console.log('Code:', event.code);
console.log('Ctrl:', event.ctrlKey);
console.log('Shift:', event.shiftKey);
console.log('Alt:', event.altKey);
// Specific key handling
if (event.key === 'Enter') {
console.log('Enter pressed');
performSearch(event.target.value);
}
if (event.key === 'Escape') {
event.target.value = '';
}
// Keyboard shortcuts
if (event.ctrlKey && event.key === 's') {
event.preventDefault();
saveDocument();
}
});
input.addEventListener('keyup', (event) => {
console.log('Key released:', event.key);
});
input.addEventListener('input', (event) => {
console.log('Input value:', event.target.value);
// Fires on every character change
});
// Mouse events
const box = document.getElementById('box');
box.addEventListener('mouseenter', () => {
console.log('Mouse entered (doesn\'t bubble)');
});
box.addEventListener('mouseleave', () => {
console.log('Mouse left (doesn\'t bubble)');
});
box.addEventListener('mouseover', () => {
console.log('Mouse over (bubbles)');
});
box.addEventListener('mouseout', () => {
console.log('Mouse out (bubbles)');
});
box.addEventListener('mousemove', (event) => {
console.log(`Position: ${event.clientX}, ${event.clientY}`);
});
box.addEventListener('mousedown', () => console.log('Mouse down'));
box.addEventListener('mouseup', () => console.log('Mouse up'));
// Focus events
const field = document.getElementById('emailField');
field.addEventListener('focus', () => {
console.log('Field focused');
field.classList.add('focused');
});
field.addEventListener('blur', () => {
console.log('Field blurred');
field.classList.remove('focused');
});
// Change event
const select = document.getElementById('category');
select.addEventListener('change', (event) => {
console.log('Selected:', event.target.value);
});
// Event listener options
button.addEventListener('click', handler, {
once: true, // Remove after first invocation
passive: true, // Won't call preventDefault()
capture: false // Use bubbling phase (default)
});
// Capture vs Bubble
parent.addEventListener('click', () => {
console.log('Parent - Capture phase');
}, true); // Capture
parent.addEventListener('click', () => {
console.log('Parent - Bubble phase');
}, false); // Bubble
child.addEventListener('click', () => {
console.log('Child - Target phase');
});
// Custom events
const myEvent = new CustomEvent('userLogin', {
detail: {
username: 'alice',
timestamp: Date.now()
},
bubbles: true,
cancelable: true
});
document.addEventListener('userLogin', (event) => {
console.log('User logged in:', event.detail);
});
document.dispatchEvent(myEvent);
// Debouncing events
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
const searchInput = document.getElementById('search');
const debouncedSearch = debounce((value) => {
console.log('Searching for:', value);
performSearch(value);
}, 300);
searchInput.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
// Throttling events
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
const throttledScroll = throttle(() => {
console.log('Scroll position:', window.scrollY);
}, 200);
window.addEventListener('scroll', throttledScroll);
// Touch events (mobile)
const touchArea = document.getElementById('touchArea');
touchArea.addEventListener('touchstart', (event) => {
console.log('Touch started');
console.log('Touches:', event.touches.length);
});
touchArea.addEventListener('touchmove', (event) => {
event.preventDefault(); // Prevent scrolling
const touch = event.touches[0];
console.log(`Touch at: ${touch.clientX}, ${touch.clientY}`);
});
touchArea.addEventListener('touchend', () => {
console.log('Touch ended');
});
// Drag and drop
const draggable = document.getElementById('draggable');
const dropZone = document.getElementById('dropZone');
draggable.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', event.target.id);
event.target.style.opacity = '0.5';
});
draggable.addEventListener('dragend', (event) => {
event.target.style.opacity = '1';
});
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // Allow drop
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
const id = event.dataTransfer.getData('text/plain');
const element = document.getElementById(id);
dropZone.appendChild(element);
dropZone.classList.remove('drag-over');
});
// Window events
window.addEventListener('resize', () => {
console.log(`Window size: ${window.innerWidth}x${window.innerHeight}`);
});
window.addEventListener('load', () => {
console.log('Page fully loaded');
});
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM ready');
});
window.addEventListener('beforeunload', (event) => {
event.preventDefault();
event.returnValue = ''; // Show confirmation dialog
});
// Cleanup pattern
class Component {
constructor(element) {
this.element = element;
this.handleClick = this.handleClick.bind(this);
this.element.addEventListener('click', this.handleClick);
}
handleClick(event) {
console.log('Component clicked');
}
destroy() {
this.element.removeEventListener('click', this.handleClick);
}
}
const component = new Component(button);
// Later: component.destroy();