DOM Events in JavaScript: A Complete Guide for Beginners

Learn how to handle DOM events in JavaScript. Discover how to useaddEventListenerTypes of events and practical step-by-step examples.
What are DOM events in JavaScript?
DOM (Document Object Model) events in JavaScript are actions or occurrences that happen in the browser and can be detected and handled by code. These events can be user-generated, such as clicking a button, moving the mouse, or pressing a key, or they can be system events, such as a page loading or the completion of a network request.
Event lifecycle: from occurrence to processing
When an event occurs in the DOM, it follows a lifecycle that includes several phases:
-
Capture: The event propagates from the DOM root element to the target element. During this phase, the event handlers registered for the capture phase are executed.
-
Target: The event reaches the target element where the action occurred. Here, the event handlers registered directly on the target element are executed.
-
Bubble: The event propagates back from the target element to the root element of the DOM. During this phase, the event handlers registered for the bubble phase are executed.
Difference between inline events and addEventListener()
Inline Events
These are events that are defined directly in the HTML using attributes such asonclick,onmouseoveretc. For example:
<button onclick="alert('¡Hola!')">Haz clic aquí</button>
Advantages:
- Easy to implement for simple events.
Disadvantages:
-
Mixture of HTML and JavaScript, which can make code maintenance difficult.
-
Does not allow adding multiple event handlers to the same element.
addEventListener()
This is a JavaScript method that allows you to add event handlers to DOM elements more flexibly. For example:
const button = document.querySelector("button");
button.addEventListener("click", () => {
alert("¡Hola!");
});
Advantages:
-
Separates HTML from JavaScript, improving code organization.
-
Allows adding multiple event handlers to the same element.
Disadvantages:
- Requires slightly more code to configure.
How to useaddEventListener to handle events
To use addEventListenerFirst, you must select the DOM element to which you want to add the event. Then, you call the method.addEventListenerpassing as arguments the type of event and the function that will be executed when the event occurs.
const button = document.querySelector("button");
button.addEventListener("click", () => {
alert("¡Hola!");
});
Common Types of Events in JavaScript
Mouse Events:click,dblclick,mouseover,mouseout,mousemove
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log("Botón clickeado");
});
button.addEventListener("dblclick", () => {
console.log("Botón doble clickeado");
});
button.addEventListener("mouseover", () => {
console.log("Mouse sobre el botón");
});
button.addEventListener("mouseout", () => {
console.log("Mouse fuera del botón");
});
button.addEventListener("mousemove", (event) => {
console.log(`Mouse moviéndose en: (${event.clientX}, ${event.clientY})`);
});
Keyboard Events:keydown,keyup,keypress
const input = document.querySelector("input");
input.addEventListener("keydown", (event) => {
console.log(`Tecla presionada: ${event.key}`);
});
input.addEventListener("keyup", (event) => {
console.log(`Tecla liberada: ${event.key}`);
});
input.addEventListener("keypress", (event) => {
console.log(`Tecla presionada (keypress): ${event.key}`);
});
Form Events:submit,change,input,focus,blur
const form = document.querySelector("form");
form.addEventListener("submit", (event) => {
event.preventDefault(); // Evita el envío del formulario
console.log("Formulario enviado");
});
const input = document.querySelector("input");
input.addEventListener("change", () => {
console.log("El valor del input ha cambiado");
});
input.addEventListener("input", () => {
console.log("El usuario está escribiendo");
});
input.addEventListener("focus", () => {
console.log("Input enfocado");
});
input.addEventListener("blur", () => {
console.log("Input desenfocado");
});
Window Events:load,resize,scroll,unload
window.addEventListener("load", () => {
console.log("Página cargada");
});
window.addEventListener("resize", () => {
console.log("Ventana redimensionada");
});
window.addEventListener("scroll", () => {
console.log("Página desplazada");
});
window.addEventListener("unload", () => {
console.log("Página descargada");
});
Event Object: What It Is and How to Access Its Properties
When an event occurs, an object is createdeventThis object contains information about the event, such as the event type, the target element, the mouse coordinates, the key pressed, and more. You can access this object by passing a parameter to the event handler function.
button.addEventListener("click", (event) => {
console.log(`Tipo de evento: ${event.type}`);
console.log(`Elemento objetivo: ${event.target}`);
});
input.addEventListener("keydown", (event) => {
console.log(`Tecla presionada: ${event.key}`);
console.log(`Código de la tecla: ${event.code}`);
});
Use ofpreventDefault()to avoid the default behavior
The methodpreventDefault()It is used to override the default behavior of an event. For example, in a form, the default behavior upon submission is to reload the page. You can usepreventDefault()To avoid this and handle form submissions with JavaScript.
form.addEventListener("submit", (event) => {
event.preventDefault(); // Evita el envío del formulario
console.log("Formulario enviado sin recargar la página");
});
Use ofstopPropagation()and event propagation
Event propagation is the process by which an event propagates through the DOM, passing through the capture, target, and bubble phases. Sometimes, you might want to prevent an event from propagating to other elements. To do this, you can use the methodstopPropagation()
const parent = document.querySelector(".parent");
const child = document.querySelector(".child");
parent.addEventListener("click", () => {
console.log("Elemento padre clickeado");
});
child.addEventListener("click", (event) => {
event.stopPropagation(); // Evita que el evento se propague al padre
console.log("Elemento hijo clickeado");
});
Event Delegation: What It Is and Why Use It
Event delegation is a technique that leverages event propagation to handle events in child elements through a single event handler in a parent element. This is especially useful when you have many similar elements (such as a list of items) and want to handle events without having to add a handler to each one.
const list = document.querySelector("ul");
list.addEventListener("click", (event) => {
if (event.target && event.target.nodeName === "LI") {
console.log(`Ítem de la lista clickeado: ${event.target.textContent}`);
}
});
Difference between Synchronous and Asynchronous Events
-
Synchronous Events: These are events that execute immediately when they occur. For example, a button click that directly executes a function.
-
Asynchronous Events: These are events that can occur at a future time and do not block code execution. For example, a network request that completes after a certain time and executes a function when it receives the response.
Using Anonymous Functions in Events
You can use anonymous functions (functions without a name) directly within theaddEventListenerfor handling events. This is useful for simple events where you don't need to reuse the function elsewhere.
button.addEventListener("click", function () {
alert("¡Hola desde una función anónima!");
});
Removing events withremoveEventListener()
To remove an event that has been added withaddEventListenerYou must use the methodremoveEventListenerIt's important that the function you want to remove is a named function or a reference to a function, since you can't remove anonymous functions directly.
function handleClick() {
alert("¡Hola!");
}
button.addEventListener("click", handleClick);
// Para remover el evento
button.removeEventListener("click", handleClick);
Custom Events withCustomEvent
You can create and trigger custom events using the class.CustomEventThis is useful when you want to communicate between different parts of your application without relying on predefined events.
const myEvent = new CustomEvent("miEvento", {
detail: { mensaje: "¡Hola desde un evento personalizado!" },
});
document.addEventListener("miEvento", (event) => {
console.log(event.detail.mensaje);
});
document.dispatchEvent(myEvent);
Touch events on mobile devices:touchstart and touchend
When users interact with a touchscreen, they don't use a mouse but their fingers. To capture these actions, JavaScript provides touch events.
Main Touch Events
-
touchstart: Triggered when a finger touches the screen. It's equivalent to the mousedown event on a mouse.
-
touchend: Occurs when the finger is lifted from the screen. It's equivalent to mouseup.
-
touchmove: Triggered while the finger is moving across the screen. It's equivalent to mousemove.
-
touchcancel: Triggered when the system interrupts the touch interaction (for example, an incoming call or switching applications).
Basic Example withtouchstart and touchend
<div
id="caja"
style="width:200px; height:200px; background:lightblue; text-align:center; line-height:200px;"
>
Tócame
</div>
<script>
const caja = document.getElementById("caja");
caja.addEventListener("touchstart", () => {
caja.style.background = "lightgreen";
caja.innerText = "¡Tocando!";
});
caja.addEventListener("touchend", () => {
caja.style.background = "lightblue";
caja.innerText = "Tócame";
});
</script>
In this example:
When the user touches the box, the background changes to green and the text to “Touching!”.
When they lift their finger, it returns to its initial state.
TouchEvent Object Properties
When working with touch events, you can access useful information:
-touchesList of all touch points on the screen.
-targetTouchesSpecific touchpoints on the element that triggered the event.
-changedTouchesTouchpoints that changed during that event.
Example:
caja.addEventListener("touchstart", (event) => {
console.log("Número de dedos en pantalla:", event.touches.length);
});
If the user taps with two fingers, it will display2
Drag and Drop Events:drag and drop
Drag and drop is a widely used feature in modern interfaces, such as moving files, rearranging elements, or creating visual editors.
JavaScript and the DOM allow us to work with these events easily.
Main Drag and Drop Events
-
dragstart: Triggered when an element begins to drag. -
drag: Occurs while the element is being dragged. -
dragend: This executes when the user stops dragging. -
dragenter: When a dragged item enters a valid target area. -
dragover: while the element moves within the valid area (must be used
````event.preventDefault()`to allow the drop).
-
dragleave: when the dragged element goes outside the valid area. -
drop: Occurs when the user drops the element onto the valid area.
Practical example: dragging and dropping a box
<div
id="zona"
style="width:300px; height:200px; border:2px dashed gray; display:flex; align-items:center; justify-content:center; margin-bottom:20px;"
>
Arrastra aquí
</div>
<div
id="caja"
draggable="true"
style="width:100px; height:100px; background:lightblue; text-align:center; line-height:100px; cursor:grab;"
>
Caja
</div>
<script>
const zona = document.getElementById("zona");
const caja = document.getElementById("caja");
// Se inicia el arrastre
caja.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text", event.target.id);
caja.style.opacity = "0.5";
});
// Finaliza el arrastre
caja.addEventListener("dragend", () => {
caja.style.opacity = "1";
});
// Permitir soltar en la zona
zona.addEventListener("dragover", (event) => {
event.preventDefault();
zona.style.background = "#e0ffe0";
});
zona.addEventListener("dragleave", () => {
zona.style.background = "";
});
// Cuando se suelta el elemento
zona.addEventListener("drop", (event) => {
event.preventDefault();
const id = event.dataTransfer.getData("text");
const elemento = document.getElementById(id);
zona.appendChild(elemento);
zona.style.background = "";
});
</script>
Example Explanation:
The draggable="true" attribute makes the element draggable.
With event.dataTransfer.setData(), we save information about the dragged element.
The dragover event must have event.preventDefault() to enable the drop.
In the drop event, we get the element with getData and insert it into the destination area.
Now you have a blue box that you can drag to the gray area and drop.
How to Combine Keyboard and Mouse Events in a Single Action
In many cases, we need the user to perform an action with the mouse but also depend on a keyboard key.
For example: clicking on an element only if the key is held downShift.
This is achieved by accessing the object's properties.eventin mouse events.
Useful object propertiesevent
-
event.shiftKey: Indicates if the keyShiftIt's under pressure. -
event.ctrlKey: Indicates if the keyControlIt's under pressure. -
event.altKey: Indicates if the keyAltIt's under pressure. -
event.metaKey: On Mac, indicates if the key⌘ Commandis pressed.
These properties can be combined with any mouse event (click,dblclick,mousedownetc.).
Practical example: Click + Shift key
<button id="btn">Haz clic aquí</button>
<script>
const btn = document.getElementById("btn");
btn.addEventListener("click", (event) => {
if (event.shiftKey) {
alert("¡Has hecho clic manteniendo presionada la tecla SHIFT!");
} else {
alert("Clic normal sin tecla SHIFT.");
}
});
</script>
In this example:
If you click the button without pressing any key → it displays "Normal click".
If you click while holding down Shift → it displays "You clicked with Shift".
Advanced example: moving an object with keyboard + click
<div
id="caja"
style="width:100px; height:100px; background:lightblue; position:absolute; top:50px; left:50px; cursor:pointer;"
>
Caja
</div>
<script>
const caja = document.getElementById("caja");
document.addEventListener("keydown", (event) => {
// Guardamos si la tecla CTRL está presionada
if (event.key === "Control") {
caja.dataset.ctrl = "true";
caja.style.border = "2px dashed red";
}
});
document.addEventListener("keyup", (event) => {
if (event.key === "Control") {
caja.dataset.ctrl = "false";
caja.style.border = "none";
}
});
caja.addEventListener("click", (event) => {
if (caja.dataset.ctrl === "true") {
// Si se hace clic con CTRL presionado → mover la caja
caja.style.left = parseInt(caja.style.left) + 50 + "px";
} else {
alert(
"Haz clic mientras mantienes presionada la tecla CTRL para mover la caja.",
);
}
});
</script>
Here we combine keyboard and mouse:
When you pressControlThe box displays a red border.
If you click the box while holding Control, it moves 50px to the right.
If you click withoutControlA warning appears.
Common Mistakes When Working with DOM Events and How to Avoid Them
Working with events in JavaScript may seem simple at first, but it's common to make mistakes that hinder an application's functionality. Below, we'll look at the most frequent errors when working with DOM events and best practices for avoiding them.
1. Usingonclick rather addEventListener
A common mistake is assigning events directly with HTML attributes (onclick="miFuncion()"This limits flexibility and can override other events.
<!-- ❌ Mala práctica -->
<button onclick="alert('Hola')">Click</button>
// ✅ Buena práctica
document.querySelector("button").addEventListener("click", () => {
alert("Hola");
});
2. Do not remove unnecessary events
Add manyaddEventListenerWithout removing them, it can cause memory leaks and an event to fire multiple times.
// ❌ Se acumulan múltiples escuchas
const btn = document.querySelector("#btn");
btn.addEventListener("click", () => console.log("Click"));
btn.addEventListener("click", () => console.log("Click otra vez"));
// ✅ Usar removeEventListener cuando ya no se necesita
function handleClick() {
console.log("Click único");
btn.removeEventListener("click", handleClick);
}
btn.addEventListener("click", handleClick);
3. Do not useevent.preventDefault()When necessary
Some elements, such as forms and links, reload the page by default, which can disrupt the expected interaction.
// ❌ Formulario recarga la página
document.querySelector("form").addEventListener("submit", () => {
console.log("Enviado");
});
// ✅ Evitar recarga con preventDefault
document.querySelector("form").addEventListener("submit", (event) => {
event.preventDefault();
console.log("Formulario procesado sin recarga");
});
4. Forgetevent.stopPropagation()
Sometimes, an event can propagate to parent elements and generate undesirable behavior.
// ❌ El click en el botón también activa el evento del contenedor
document.querySelector("#contenedor").addEventListener("click", () => {
console.log("Click en contenedor");
});
document.querySelector("#boton").addEventListener("click", () => {
console.log("Click en botón");
});
// ✅ Detener la propagación
document.querySelector("#boton").addEventListener("click", (event) => {
event.stopPropagation();
console.log("Click solo en botón");
});
5. Not delegating events when necessary
If you have many dynamic elements, adding an addEventListener to each one can be inefficient.
// ❌ Se agregan eventos a cada botón
document.querySelectorAll(".btn").forEach((btn) => {
btn.addEventListener("click", () => console.log("Click en botón"));
});
// ✅ Delegar evento en el contenedor
document.querySelector("#contenedor").addEventListener("click", (event) => {
if (event.target.classList.contains("btn")) {
console.log("Click en botón delegado");
}
});
Practical Example: Counter with Button and Events
let count = 0;
const button = document.querySelector("button");
const display = document.querySelector("#display");
button.addEventListener("click", () => {
count++;
display.textContent = `Contador: ${count}`;
});
Practical Example: Event-Driven Pop-Up Modal
const openModalBtn = document.querySelector("#openModal");
const closeModalBtn = document.querySelector("#closeModal");
const modal = document.querySelector("#myModal");
openModalBtn.addEventListener("click", () => {
modal.style.display = "block";
});
closeModalBtn.addEventListener("click", () => {
modal.style.display = "none";
});
window.addEventListener("click", (event) => {
if (event.target === modal) {
modal.style.display = "none";
}
});
-
Array methods in JavaScript:Array methods in JavaScript: A guide with examples and exercises
-
JSON data in JavaScript:JSON in JavaScript: What it is and how to use it with practical examples
-
Local Storage in JavaScript: Local Storage in JavaScript: A Complete Guide for Beginners
-
More about events:mdn - Introduction to events
💻Try this basic exercise on events in JavaScript: