JavaScript Event Listeners: Complete Guide with 10 Real-World Examples
Introduction
Event listeners make websites interactive. They detect user actions like clicks, typing, scrolling, and trigger your code instantly.
This guide covers 10 practical examples you'll use daily, from basic button clicks to advanced event delegation. Perfect for web developers building modern applications.
What Are Event Listeners?
javascriptelement.addEventListener('click', function() { // Code runs when clicked });
Key Benefits:
Multiple listeners per element (unlike
onclick)Easy to remove
Access to event object (
e.target,e.key, etc.)Works with event bubbling/capturing
Example 1: Basic Button Click
xml<!DOCTYPE html> <html> <head> <title>Event Listener Example</title> </head> <body> <button id="myBtn">Click Me!</button> <p id="message"></p> <script> const btn = document.getElementById('myBtn'); const message = document.getElementById('message'); btn.addEventListener('click', function() { message.textContent = 'Button clicked!'; message.style.color = 'green'; btn.style.backgroundColor = '#4CAF50'; }); </script> </body> </html>
What happens: Button changes color + shows message on click.
Example 2: Real-Time Form Validation
xml<input type="email" id="emailInput" placeholder="Enter email"> <span id="feedback"></span> <script> const input = document.getElementById('emailInput'); const feedback = document.getElementById('feedback'); input.addEventListener('input', function(e) { const email = e.target.value; const isValid = email.includes('@') && email.includes('.'); if (isValid) { feedback.textContent = '✓ Valid email'; feedback.style.color = 'green'; } else { feedback.textContent = '✗ Enter valid email'; feedback.style.color = 'red'; } }); </script>
Key learning: input event fires on every keystroke for live validation.
Example 3: Keyboard Events (Enter Key Search)
xml<input type="text" id="searchBox" placeholder="Press Enter to search"> <p id="result"></p> <script> const searchBox = document.getElementById('searchBox'); const result = document.getElementById('result'); searchBox.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const query = e.target.value; result.textContent = `Searching for: "${query}"`; console.log('Search:', query); } }); </script>
Pro tip: Use keydown for Enter detection, not keyup.youtube
Example 4: Mouse Hover Effects
xml<div id="hoverBox" style="width:200px;height:100px;background:blue;color:white;padding:20px;"> Hover over me </div> <p id="status"></p> <script> const box = document.getElementById('hoverBox'); const status = document.getElementById('status'); box.addEventListener('mouseenter', function() { box.style.background = 'orange'; status.textContent = 'Mouse entered!'; }); box.addEventListener('mouseleave', function() { box.style.background = 'blue'; status.textContent = 'Mouse left!'; }); </script>
Example 5: Infinite Scroll Detection
xml<div id="content" style="height:200px;overflow-y:scroll;border:1px solid #ccc;padding:20px;"> Scroll to bottom for more content... <!-- Long content here --> </div> <script> const content = document.getElementById('content'); content.addEventListener('scroll', function() { const { scrollTop, scrollHeight, clientHeight } = content; const scrolledToBottom = scrollTop + clientHeight >= scrollHeight - 5; if (scrolledToBottom) { content.innerHTML += '<p>New content loaded!</p>'; console.log('Load more content'); } }); </script>
Use case: Social media feeds, infinite pagination.youtube
Example 6: Form Submission (Prevent Default)
xml<form id="contactForm"> <input type="text" name="name" required> <input type="email" name="email" required> <button type="submit">Submit</button> </form> <p id="status"></p> <script> const form = document.getElementById('contactForm'); const status = document.getElementById('status'); form.addEventListener('submit', function(e) { e.preventDefault(); // Stops page refresh const formData = new FormData(form); const name = formData.get('name'); const email = formData.get('email'); status.textContent = `Thanks ${name}! We'll contact ${email}.`; status.style.color = 'green'; // Send to API fetch('/api/contact', { method: 'POST', body: formData }); }); </script>
Example 7: Event Delegation (Dynamic Lists)
xml<ul id="todoList"> <li>Task 1</li> <li>Task 2</li> </ul> <button id="addTask">Add Task</button> <script> const list = document.getElementById('todoList'); const addBtn = document.getElementById('addTask'); let count = 3; // Single listener for ALL list items (current + future) list.addEventListener('click', function(e) { if (e.target.tagName === 'LI') { e.target.style.textDecoration = 'line-through'; e.target.style.color = 'gray'; } }); addBtn.addEventListener('click', function() { const li = document.createElement('li'); li.textContent = `Task ${count++}`; list.appendChild(li); // New items automatically work! }); </script>
Why delegation: Efficient for 100s of dynamic elements.youtube
Example 8: Remove Event Listener
xml<button id="toggleBtn">Toggle Listener</button> <button id="targetBtn">Target Button</button> <p id="message"></p> <script> const target = document.getElementById('targetBtn'); const toggle = document.getElementById('toggleBtn'); const message = document.getElementById('message'); // Named function (required for removal) function handleClick() { message.textContent = 'Clicked!'; } let listenerActive = false; toggle.addEventListener('click', function() { if (listenerActive) { target.removeEventListener('click', handleClick); message.textContent = 'Listener removed'; listenerActive = false; } else { target.addEventListener('click', handleClick); message.textContent = 'Listener added'; listenerActive = true; } }); </script>
Example 9: Dark Mode Toggle (localStorage)
xml<button id="themeBtn">🌙 Dark Mode</button> <script> const btn = document.getElementById('themeBtn'); const html = document.documentElement; // Load saved theme const savedTheme = localStorage.getItem('theme') || 'light'; html.setAttribute('data-theme', savedTheme); btn.textContent = savedTheme === 'dark' ? '☀️ Light Mode' : '🌙 Dark Mode'; btn.addEventListener('click', function() { const current = html.getAttribute('data-theme'); const newTheme = current === 'dark' ? 'light' : 'dark'; html.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); btn.textContent = newTheme === 'dark' ? '☀️ Light Mode' : '🌙 Dark Mode'; }); </script>
CSS needed:
css[data-theme="dark"] { background: #121212; color: white; }
Example 10: Drag & Drop File Upload
xml<div id="dropZone" style="width:300px;height:200px;border:2px dashed #ccc;padding:50px;text-align:center;"> Drop files here </div> <p id="fileInfo"></p> <script> const dropZone = document.getElementById('dropZone'); const info = document.getElementById('fileInfo'); ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { dropZone.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, unhighlight, false); }); function highlight(e) { dropZone.style.background = '#4CAF50'; } function unhighlight(e) { dropZone.style.background = ''; } dropZone.addEventListener('drop', handleDrop, false); function handleDrop(e) { const files = e.dataTransfer.files; info.textContent = `Dropped ${files.length} files`; Array.from(files).forEach(file => { console.log('File:', file.name, file.size); }); } </script>
Event Listener Options (Advanced)
javascript// Run only once btn.addEventListener('click', handler, { once: true }); // Capture phase (top-down) btn.addEventListener('click', handler, { capture: true }); // Passive (better scroll performance) window.addEventListener('scroll', handler, { passive: true });
Conclusion
Master these 10 patterns and you'll handle 95% of JavaScript interactivity. Copy the code examples, test them, and integrate into your projects.
Next steps:
Test all 10 examples in CodePen
Add dark mode toggle to your site today
Implement event delegation in your lists
Practice
preventDefault()with forms
Join the conversation