The event loop and event queue work together to allow JavaScript to handle multiple tasks, ensuring asynchronous code runs after synchronous code.
console.log("Start"); setTimeout(() => { console.log("Timeout"); }, 0); console.log("End");
Explanation: The "Start" and "End" logs appear first, as they are synchronous. The callback from setTimeout
is placed in the event queue and processed after the synchronous code finishes.
Output:
Event bubbling occurs when an event triggered on an element bubbles up through its ancestors. Capturing occurs when the event starts from the root and moves toward the target.
<div id="parent"> <button id="child">Click Me</button> </div> <script> document.getElementById("parent").addEventListener("click", () => { alert("Parent clicked!"); }); document.getElementById("child").addEventListener("click", () => { alert("Button clicked!"); }); </script>
Explanation: Clicking the button triggers the click
event for both the button (child) and the parent div. The event bubbles up from the button to the parent.
Output:
To enable capturing, you can pass true
as the third argument in the addEventListener
method.
<div id="parent"> <button id="child">Click Me</button> </div> <script> document.getElementById("parent").addEventListener("click", () => { alert("Parent clicked!"); }, true); // Capturing phase document.getElementById("child").addEventListener("click", () => { alert("Button clicked!"); }); </script>
Explanation: In capturing mode, the parent event triggers before the child event, as the event is captured first before bubbling to the target.
Output:
Event delegation involves attaching a single event listener to a parent element, allowing it to manage events for multiple child elements.
<ul id="parent"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <script> document.getElementById("parent").addEventListener("click", (event) => { if (event.target.tagName === "LI") { alert(`Item clicked: ${event.target.textContent}`); } }); </script>
Explanation: The event listener is attached to the parent element, and the target is checked in the callback function. This way, even dynamically added <li>
elements will be handled.
Output:
Here are some common event types:
<input type="text" id="myInput" placeholder="Type something"> <script> document.getElementById("myInput").addEventListener("keydown", (event) => { console.log(`Key pressed: ${event.key}`); }); </script>
Explanation: The keydown
event triggers when a key is pressed, and logs the key name in the console.
Output:
You can add and remove event listeners to dynamically control the behavior of elements.
<button id="myButton">Click Me</button> <script> function handleClick() { alert("Button clicked!"); } const button = document.getElementById("myButton"); button.addEventListener("click", handleClick); setTimeout(() => { button.removeEventListener("click", handleClick); console.log("Event listener removed!"); }, 3000); </script>
Explanation: The event listener is removed after 3 seconds, so clicks after that time will not trigger the alert.
Output: