JavaScript

JavaScript

Tutorial JavaScript: Eventos del DOM

JavaScript DOM: manipulación y uso. Domina la manipulación y uso del DOM en JavaScript con ejemplos prácticos y detallados.

Aprende JavaScript y certifícate

Fases de propagación

Cuando interactuamos con elementos en una página web, los eventos del DOM no simplemente ocurren en el elemento que los desencadena, sino que siguen un camino predecible a través del árbol de elementos. Este recorrido se conoce como propagación de eventos y es fundamental para entender cómo JavaScript maneja las interacciones del usuario.

La propagación de eventos en el DOM ocurre en tres fases distintas y secuenciales:

  • Fase de captura: El evento desciende desde el elemento window hasta el elemento objetivo
  • Fase de objetivo: El evento alcanza el elemento donde ocurrió originalmente
  • Fase de burbujeo: El evento asciende desde el elemento objetivo hasta window

Visualización del flujo de eventos

Para entender mejor estas fases, imaginemos una estructura HTML simple:

<div id="outer">
  <div id="inner">
    <button id="button">Click me</button>
  </div>
</div>

Cuando hacemos clic en el botón, el evento sigue este recorrido:

  1. Fase de captura: windowdocument<html><body><div id="outer"><div id="inner"><button>
  2. Fase de objetivo: <button>
  3. Fase de burbujeo: <button><div id="inner"><div id="outer"><body><html>documentwindow

Controlando la fase de escucha

Por defecto, los event listeners se ejecutan durante la fase de burbujeo. Sin embargo, podemos configurarlos para que se activen durante la fase de captura utilizando el tercer parámetro del método addEventListener():

element.addEventListener(eventType, handler, useCapture);

Donde useCapture es un booleano:

  • false (valor predeterminado): El listener se ejecuta en la fase de burbujeo
  • true: El listener se ejecuta en la fase de captura

Ejemplo práctico de las tres fases

Veamos un ejemplo que demuestra las tres fases de propagación:

const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const button = document.getElementById('button');

// Fase de captura (tercer parámetro: true)
outer.addEventListener('click', () => {
  console.log('Outer - Fase de captura');
}, true);

inner.addEventListener('click', () => {
  console.log('Inner - Fase de captura');
}, true);

// Fase de objetivo y burbujeo (tercer parámetro: false)
button.addEventListener('click', () => {
  console.log('Button - Fase de objetivo');
});

inner.addEventListener('click', () => {
  console.log('Inner - Fase de burbujeo');
});

outer.addEventListener('click', () => {
  console.log('Outer - Fase de burbujeo');
});

Al hacer clic en el botón, la consola mostrará:

Outer - Fase de captura
Inner - Fase de captura
Button - Fase de objetivo
Inner - Fase de burbujeo
Outer - Fase de burbujeo

Deteniendo la propagación

En ocasiones, necesitamos detener la propagación de un evento para evitar que se ejecuten listeners en elementos padres. Para esto tenemos dos métodos principales:

  • event.stopPropagation(): Detiene la propagación del evento, pero permite que otros listeners del mismo elemento se ejecuten
  • event.stopImmediatePropagation(): Detiene la propagación y evita que se ejecuten otros listeners del mismo elemento
button.addEventListener('click', (event) => {
  console.log('Button clicked');
  event.stopPropagation();
  // Los listeners de los elementos padres no se ejecutarán
});

Fase de captura en la práctica

La fase de captura es menos utilizada que la de burbujeo, pero puede ser útil en escenarios específicos:

// Interceptar eventos antes de que lleguen al objetivo
document.addEventListener('click', (event) => {
  // Verificar si el usuario está autorizado
  if (!userIsAuthorized && event.target.classList.contains('restricted')) {
    event.stopPropagation();
    showLoginPrompt();
  }
}, true); // Usar fase de captura

Event.currentTarget vs Event.target

Al trabajar con propagación de eventos, es importante distinguir entre:

  • event.target: El elemento donde originalmente ocurrió el evento
  • event.currentTarget: El elemento cuyo listener está ejecutándose actualmente
outer.addEventListener('click', (event) => {
  console.log('Target:', event.target.id);       // 'button' (si se hizo clic en el botón)
  console.log('Current Target:', event.currentTarget.id); // 'outer'
});

Configuración moderna de addEventListener

En versiones modernas de JavaScript, el tercer parámetro de addEventListener puede ser un objeto con opciones avanzadas:

element.addEventListener('click', handler, {
  capture: false,    // Equivalente a useCapture
  once: true,        // El listener se ejecuta solo una vez
  passive: true      // Mejora el rendimiento en eventos táctiles
});

Entender las fases de propagación de eventos es esencial para crear interfaces interactivas eficientes y para implementar patrones como la delegación de eventos, que veremos en la siguiente sección.

Delegación de eventos: Implementación eficiente para elementos dinámicos

La delegación de eventos es un patrón de diseño en JavaScript que aprovecha la fase de burbujeo del DOM para manejar eventos de manera más eficiente, especialmente cuando trabajamos con elementos que se crean o eliminan dinámicamente. En lugar de asignar event listeners a cada elemento individual, este patrón consiste en asignar un único listener a un elemento ancestro que procesará los eventos de todos sus descendientes.

Problema que resuelve la delegación

Imaginemos una lista de tareas donde constantemente añadimos o eliminamos elementos:

<ul id="taskList">
  <li class="task">Tarea 1 <button class="delete">×</button></li>
  <li class="task">Tarea 2 <button class="delete">×</button></li>
  <!-- Más tareas se añadirán dinámicamente -->
</ul>

Sin delegación, tendríamos que hacer algo así:

// Enfoque problemático: añadir listeners a cada botón
document.querySelectorAll('.delete').forEach(button => {
  button.addEventListener('click', handleDelete);
});

// Problema: los nuevos botones añadidos no tendrán el listener

Este enfoque presenta dos problemas principales:

  • Cada elemento necesita su propio listener, consumiendo memoria
  • Los elementos creados dinámicamente después de asignar los listeners no responderán a eventos

Implementación básica de delegación

La solución es utilizar la delegación de eventos:

// Un único listener en el contenedor padre
const taskList = document.getElementById('taskList');

taskList.addEventListener('click', (event) => {
  if (event.target.classList.contains('delete')) {
    const taskItem = event.target.closest('.task');
    taskItem.remove();
  }
});

Con este enfoque:

  • Asignamos un único listener al elemento contenedor
  • Verificamos si el elemento que originó el evento (event.target) es el que nos interesa
  • Aplicamos la lógica correspondiente solo cuando es necesario

Identificación precisa del elemento objetivo

Para identificar correctamente el elemento que desencadenó el evento, podemos usar diferentes técnicas:

document.getElementById('container').addEventListener('click', (event) => {
  // Por clase CSS
  if (event.target.classList.contains('button')) {
    // Acción para botones
  }
  
  // Por atributo data
  if (event.target.dataset.action === 'edit') {
    // Acción para elementos con data-action="edit"
  }
  
  // Por selector de coincidencia
  if (event.target.matches('.item > .icon')) {
    // Acción para iconos dentro de items
  }
});

Método closest() para elementos anidados

Cuando trabajamos con elementos anidados, el método closest() es extremadamente útil para encontrar el ancestro más cercano que coincida con un selector:

document.getElementById('shoppingList').addEventListener('click', (event) => {
  // Si hacemos clic en cualquier elemento dentro de un item
  const listItem = event.target.closest('li');
  
  if (listItem) {
    // Verificamos si el clic fue en el botón de eliminar
    if (event.target.classList.contains('delete')) {
      listItem.remove();
    } 
    // Verificamos si el clic fue en el botón de editar
    else if (event.target.classList.contains('edit')) {
      editItem(listItem);
    }
  }
});

Delegación con múltiples tipos de eventos

La delegación funciona con cualquier tipo de evento que se propague:

const form = document.getElementById('userForm');

// Delegación para diferentes tipos de eventos
form.addEventListener('input', handleFormChanges);
form.addEventListener('change', handleFormChanges);
form.addEventListener('submit', handleFormSubmit);

function handleFormChanges(event) {
  const target = event.target;
  
  if (target.matches('input[type="text"]')) {
    validateTextField(target);
  } else if (target.matches('select')) {
    updateDependentFields(target);
  }
}

Ventajas de la delegación de eventos

  • Rendimiento mejorado: Menos listeners significa menos sobrecarga de memoria
  • Manejo dinámico: Funciona automáticamente con elementos añadidos dinámicamente
  • Código más limpio: Centraliza la lógica de manejo de eventos
  • Menos fugas de memoria: Evita problemas con listeners huérfanos cuando se eliminan elementos

Ejemplo práctico: Tabla de datos interactiva

Veamos un ejemplo más completo de una tabla con múltiples acciones:

const dataTable = document.getElementById('dataTable');

dataTable.addEventListener('click', (event) => {
  const target = event.target;
  const row = target.closest('tr');
  
  // No procesar si no hay fila o es el encabezado
  if (!row || row.parentElement.tagName === 'THEAD') return;
  
  // Determinar la acción según el elemento clicado
  if (target.classList.contains('btn-edit')) {
    openEditModal(row.dataset.id);
  } else if (target.classList.contains('btn-delete')) {
    confirmDelete(row.dataset.id);
  } else if (target.tagName === 'TD' && !target.classList.contains('no-select')) {
    toggleRowSelection(row);
  }
});

Limitaciones de la delegación

Aunque la delegación es poderosa, tiene algunas limitaciones:

  • No funciona con eventos que no se propagan (como focus y blur en algunos navegadores)
  • Para estos casos, podemos usar los eventos focusin y focusout que sí se propagan:
// Delegación para eventos de foco
document.getElementById('formContainer').addEventListener('focusin', (event) => {
  if (event.target.tagName === 'INPUT') {
    event.target.classList.add('active');
  }
});

document.getElementById('formContainer').addEventListener('focusout', (event) => {
  if (event.target.tagName === 'INPUT') {
    event.target.classList.remove('active');
  }
});

Delegación con elementos deshabilitados

Los elementos con el atributo disabled no disparan eventos, lo que puede complicar la delegación:

// Solución: usar data-attributes en lugar de disabled
document.querySelectorAll('[data-disabled="true"]').forEach(el => {
  el.setAttribute('aria-disabled', 'true');
  // No usar el atributo disabled, sino simular su comportamiento
});

container.addEventListener('click', (event) => {
  if (event.target.getAttribute('aria-disabled') === 'true') {
    event.preventDefault();
    return false;
  }
  // Continuar con el manejo normal
});

La delegación de eventos es una técnica fundamental para crear interfaces web eficientes y mantenibles, especialmente cuando trabajamos con contenido dinámico o listas extensas de elementos interactivos.

Eventos personalizados: Creación, dispatch y comunicación entre componentes

Los eventos personalizados en JavaScript permiten extender el sistema de eventos del DOM para crear una comunicación flexible entre componentes de una aplicación. A diferencia de los eventos nativos como click o submit, los eventos personalizados son definidos por el desarrollador para representar acciones específicas de la aplicación.

Fundamentos de eventos personalizados

Los eventos personalizados se crean utilizando la interfaz CustomEvent, que extiende la interfaz básica Event añadiendo la capacidad de transportar datos personalizados:

// Creación básica de un evento personalizado
const event = new CustomEvent('userLogin', {
  bubbles: true,
  cancelable: true,
  detail: { userId: 42, username: 'john_doe' }
});

El constructor CustomEvent acepta dos parámetros:

  • El nombre del evento (string)
  • Un objeto de opciones con las siguientes propiedades:
  • bubbles: Determina si el evento se propaga en el árbol DOM (default: false)
  • cancelable: Indica si el evento puede ser cancelado (default: false)
  • detail: Objeto que contiene los datos personalizados que queremos transmitir

Disparando eventos personalizados

Una vez creado el evento, podemos dispararlo (dispatch) en cualquier elemento del DOM:

// Crear el evento
const productAddedEvent = new CustomEvent('productAdded', {
  bubbles: true,
  detail: { 
    productId: 'abc123',
    quantity: 2,
    price: 29.99
  }
});

// Disparar el evento desde un elemento
document.getElementById('addToCartButton').addEventListener('click', () => {
  // Lógica para añadir al carrito
  
  // Notificar a otros componentes mediante el evento personalizado
  document.dispatchEvent(productAddedEvent);
});

Escuchando eventos personalizados

Para escuchar eventos personalizados, utilizamos addEventListener exactamente igual que con eventos nativos:

// Escuchar el evento personalizado
document.addEventListener('productAdded', (event) => {
  const { productId, quantity, price } = event.detail;
  
  // Actualizar el contador del carrito
  updateCartCounter(quantity);
  
  // Mostrar notificación
  showNotification(`Producto añadido: $${price}`);
});

Comunicación entre componentes

Los eventos personalizados son ideales para implementar una arquitectura basada en eventos donde los componentes se comunican sin acoplarse directamente:

// Componente emisor (ShoppingCart)
class ShoppingCart {
  addItem(product) {
    // Lógica para añadir el producto
    this.items.push(product);
    
    // Notificar a otros componentes
    const event = new CustomEvent('cart:changed', {
      bubbles: true,
      detail: { 
        items: this.items,
        totalItems: this.items.length,
        totalPrice: this.calculateTotal()
      }
    });
    
    document.dispatchEvent(event);
  }
}

// Componente receptor (CartIndicator)
class CartIndicator {
  constructor() {
    this.element = document.querySelector('.cart-indicator');
    
    // Escuchar cambios en el carrito
    document.addEventListener('cart:changed', this.update.bind(this));
  }
  
  update(event) {
    const { totalItems } = event.detail;
    this.element.textContent = totalItems;
    
    if (totalItems > 0) {
      this.element.classList.add('active');
    }
  }
}

Eventos con namespace

Una buena práctica es utilizar namespaces (espacios de nombres) para organizar los eventos personalizados y evitar colisiones:

// Eventos con namespace usando el patrón 'dominio:acción'
const events = {
  cart: {
    ITEM_ADDED: 'cart:itemAdded',
    ITEM_REMOVED: 'cart:itemRemoved',
    CLEARED: 'cart:cleared'
  },
  auth: {
    LOGIN: 'auth:login',
    LOGOUT: 'auth:logout',
    SESSION_EXPIRED: 'auth:sessionExpired'
  }
};

// Uso
document.dispatchEvent(new CustomEvent(events.auth.LOGIN, {
  bubbles: true,
  detail: { user: currentUser }
}));

Cancelación de eventos personalizados

Los eventos personalizados pueden ser cancelables, lo que permite a los receptores detener el flujo normal:

// Crear un evento cancelable
const beforeSubmitEvent = new CustomEvent('form:beforeSubmit', {
  bubbles: true,
  cancelable: true,  // Importante para permitir cancelación
  detail: { formData: formData }
});

// Disparar y verificar si fue cancelado
document.getElementById('userForm').addEventListener('submit', function(e) {
  e.preventDefault();
  
  // Disparar evento personalizado antes de enviar
  const canContinue = this.dispatchEvent(beforeSubmitEvent);
  
  if (canContinue) {
    // Nadie canceló el evento, continuar con el envío
    submitFormData();
  } else {
    console.log('Envío cancelado por un listener');
  }
});

// Listener que puede cancelar el evento
document.addEventListener('form:beforeSubmit', (event) => {
  const { formData } = event.detail;
  
  // Validación personalizada
  if (!validateCustomRules(formData)) {
    // Cancelar el evento
    event.preventDefault();
    showValidationErrors();
  }
});

Eventos de un solo uso

Para situaciones donde solo necesitamos escuchar un evento una vez, podemos usar la opción once:

document.addEventListener('app:initialized', (event) => {
  // Configuración que solo debe ejecutarse una vez
  setupInitialState(event.detail.config);
}, { once: true });

Patrón de bus de eventos

Para aplicaciones más complejas, podemos implementar un bus de eventos centralizado:

// Implementación simple de un bus de eventos
class EventBus {
  constructor() {
    this.eventTarget = new EventTarget();
  }
  
  on(eventName, listener) {
    this.eventTarget.addEventListener(eventName, listener);
  }
  
  off(eventName, listener) {
    this.eventTarget.removeEventListener(eventName, listener);
  }
  
  once(eventName, listener) {
    this.eventTarget.addEventListener(eventName, listener, { once: true });
  }
  
  emit(eventName, detail = {}) {
    const event = new CustomEvent(eventName, { detail });
    this.eventTarget.dispatchEvent(event);
  }
}

// Uso del bus de eventos
const bus = new EventBus();

// Componente A
bus.on('userUpdated', (event) => {
  updateUserInterface(event.detail);
});

// Componente B
function saveUserData(userData) {
  // Guardar datos
  api.updateUser(userData).then(() => {
    bus.emit('userUpdated', userData);
  });
}

Eventos personalizados y Web Components

Los eventos personalizados son especialmente útiles cuando trabajamos con Web Components, permitiendo una comunicación desacoplada:

// Componente personalizado que emite eventos
class ProductCard extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    // Configuración del componente...
  }
  
  connectedCallback() {
    this.shadowRoot.innerHTML = `
      <div class="product">
        <h3>${this.getAttribute('name')}</h3>
        <p>$${this.getAttribute('price')}</p>
        <button class="add-to-cart">Añadir al carrito</button>
      </div>
    `;
    
    this.shadowRoot.querySelector('.add-to-cart').addEventListener('click', () => {
      // Emitir evento que atraviesa el Shadow DOM
      this.dispatchEvent(new CustomEvent('product:added', {
        bubbles: true,
        composed: true, // Permite que el evento atraviese el límite del Shadow DOM
        detail: {
          id: this.getAttribute('product-id'),
          name: this.getAttribute('name'),
          price: parseFloat(this.getAttribute('price'))
        }
      }));
    });
  }
}

customElements.define('product-card', ProductCard);

Los eventos personalizados proporcionan un mecanismo poderoso para crear sistemas de comunicación flexibles y desacoplados entre los diferentes componentes de una aplicación web moderna, facilitando la creación de arquitecturas escalables y mantenibles.

Aprende JavaScript online

Otras lecciones de JavaScript

Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Javascript

JavaScript

Introducción Y Entorno

Tipos De Datos

JavaScript

Sintaxis

Variables

JavaScript

Sintaxis

Operadores

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Métodos De Strings

JavaScript

Sintaxis

Funciones Cierre (Closure)

JavaScript

Sintaxis

Operadores Avanzados

JavaScript

Sintaxis

Funciones

JavaScript

Sintaxis

Expresiones Regulares

JavaScript

Sintaxis

Estructuras De Control

JavaScript

Sintaxis

Arrays Y Métodos

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Mapas Con Map

JavaScript

Estructuras De Datos

Conjuntos Con Set

JavaScript

Estructuras De Datos

Funciones Flecha

JavaScript

Programación Funcional

Filtrado Con Filter() Y Find()

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Reducción Con Reduce()

JavaScript

Programación Funcional

Funciones Flecha

JavaScript

Programación Funcional

Transformación Con Map()

JavaScript

Programación Funcional

Inmutabilidad Y Programación Funcional Pura

JavaScript

Programación Funcional

Clases Y Objetos

JavaScript

Programación Orientada A Objetos

Excepciones

JavaScript

Programación Orientada A Objetos

Encapsulación

JavaScript

Programación Orientada A Objetos

Herencia

JavaScript

Programación Orientada A Objetos

Polimorfismo

JavaScript

Programación Orientada A Objetos

This Y Contexto

JavaScript

Programación Orientada A Objetos

Patrón De Módulos Y Namespace

JavaScript

Programación Orientada A Objetos

Prototipos Y Cadena De Prototipos

JavaScript

Programación Orientada A Objetos

Destructuring De Objetos Y Arrays

JavaScript

Programación Orientada A Objetos

Manipulación Dom

JavaScript

Dom

Selección De Elementos Dom

JavaScript

Dom

Modificación De Elementos Dom

JavaScript

Dom

Eventos Del Dom

JavaScript

Dom

Localstorage Y Sessionstorage

JavaScript

Dom

Bom (Browser Object Model)

JavaScript

Dom

Callbacks

JavaScript

Programación Asíncrona

Promises

JavaScript

Programación Asíncrona

Async / Await

JavaScript

Programación Asíncrona

Api Fetch

JavaScript

Programación Asíncrona

Naturaleza De Js Y Event Loop

JavaScript

Programación Asíncrona

Websockets

JavaScript

Programación Asíncrona

Módulos En Es6

JavaScript

Construcción

Configuración De Bundlers Como Vite

JavaScript

Construcción

Eslint Y Calidad De Código

JavaScript

Construcción

Npm Y Dependencias

JavaScript

Construcción

Introducción A Pruebas En Js

JavaScript

Testing

Pruebas Unitarias

JavaScript

Testing

Accede GRATIS a JavaScript y certifícate

Ejercicios de programación de JavaScript

Evalúa tus conocimientos de esta lección Eventos del DOM con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Excepciones

JavaScript
Test

Transformación con map()

JavaScript
Código

Arrays y Métodos

JavaScript
Código

Reto Métodos de Strings

JavaScript
Código

Transformación con map()

JavaScript
Puzzle

Funciones flecha

JavaScript
Test

Selección de elementos DOM

JavaScript
Puzzle

API Fetch

JavaScript
Código

Encapsulación

JavaScript
Test

Mapas con Map

JavaScript
Código

Creación y uso de variables

JavaScript
Puzzle

Polimorfismo

JavaScript
Puzzle

Reto Funciones flecha

JavaScript
Código

Tipos de datos

JavaScript
Puzzle

Reto Operadores avanzados

JavaScript
Código

Reto Estructuras de control

JavaScript
Código

Estructuras de control

JavaScript
Puzzle

Pruebas unitarias

JavaScript
Proyecto

Inmutabilidad y programación funcional pura

JavaScript
Código

Funciones flecha

JavaScript
Puzzle

Polimorfismo

JavaScript
Test

Reto Polimorfismo

JavaScript
Código

Array

JavaScript
Código

Transformación con map()

JavaScript
Test

Reto Variables

JavaScript
Código

Gestor de tareas con JavaScript

JavaScript
Proyecto

Proyecto Modificación de elementos DOM

JavaScript
Proyecto

Manipulación DOM

JavaScript
Test

Funciones

JavaScript
Test

Conjuntos con Set

JavaScript
Código

Reto Prototipos y cadena de prototipos

JavaScript
Código

Reto Encapsulación

JavaScript
Código

Funciones flecha

JavaScript
Código

Async / Await

JavaScript
Código

Reto Excepciones

JavaScript
Código

Reto Filtrado con filter() y find()

JavaScript
Código

Reto Promises

JavaScript
Código

Creación y uso de variables

JavaScript
Test

Excepciones

JavaScript
Puzzle

Promises

JavaScript
Código

Funciones cierre (closure)

JavaScript
Test

Reto Herencia

JavaScript
Código

Herencia

JavaScript
Puzzle

Reto Async / Await

JavaScript
Código

Proyecto Eventos del DOM

JavaScript
Proyecto

Herencia

JavaScript
Test

Selección de elementos DOM

JavaScript
Test

Modificación de elementos DOM

JavaScript
Test

Reto Clases y objetos

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Test

Funciones cierre (closure)

JavaScript
Puzzle

Reto Destructuring de objetos y arrays

JavaScript
Código

Callbacks

JavaScript
Código

Funciones

JavaScript
Puzzle

Mapas con Map

JavaScript
Test

Reducción con reduce()

JavaScript
Test

Callbacks

JavaScript
Puzzle

Manipulación DOM

JavaScript
Puzzle

Introducción al DOM

JavaScript
Proyecto

Reto Funciones

JavaScript
Código

Reto Funciones cierre (closure)

JavaScript
Código

Promises

JavaScript
Test

Reto Reducción con reduce()

JavaScript
Código

Async / Await

JavaScript
Test

Reto Estructuras de control

JavaScript
Código

Eventos del DOM

JavaScript
Puzzle

Introducción a JavaScript

JavaScript
Puzzle

Async / Await

JavaScript
Puzzle

Promises

JavaScript
Puzzle

Selección de elementos DOM

JavaScript
Proyecto

Filtrado con filter() y find()

JavaScript
Código

Callbacks

JavaScript
Test

Creación de clases y objetos Restaurante

JavaScript
Código

Reducción con reduce()

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Puzzle

Reducción con reduce()

JavaScript
Puzzle

Conjuntos con Set

JavaScript
Puzzle

Herencia de clases

JavaScript
Código

Eventos del DOM

JavaScript
Test

Clases y objetos

JavaScript
Puzzle

Modificación de elementos DOM

JavaScript
Puzzle

Mapas con Map

JavaScript
Puzzle

Proyecto carrito compra agoodshop

JavaScript
Proyecto

Introducción a JavaScript

JavaScript
Test

Reto Mapas con Map

JavaScript
Código

Funciones

JavaScript
Código

Proyecto administrador de contactos

JavaScript
Proyecto

Reto Expresiones regulares

JavaScript
Código

Tipos de datos

JavaScript
Test

Clases y objetos

JavaScript
Test

Array

JavaScript
Test

Conjuntos con Set

JavaScript
Test

Array

JavaScript
Puzzle

Encapsulación

JavaScript
Puzzle

Clases y objetos

JavaScript
Código

Uso de operadores

JavaScript
Puzzle

Uso de operadores

JavaScript
Test

Estructuras de control

JavaScript
Test

Proyecto Manipulación DOM

JavaScript
Proyecto

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender la importancia de los eventos del DOM en el desarrollo web.
  2. Aprender a utilizar los escuchadores de eventos para detectar y responder a eventos específicos.
  3. Conocer algunos de los eventos del DOM más comúnmente utilizados, como 'click', 'dblclick', 'mouseenter', 'mouseleave', 'keydown', 'keyup', 'load', 'submit', y 'change'.
  4. Entender cómo pasar funciones de callback como argumentos a los escuchadores de eventos y cómo trabajar con el objeto de evento para obtener información sobre el evento que ocurrió.
  5. Aprender cómo crear interactividad en una página web mediante la detección y respuesta a eventos del DOM.