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: