querySelector, modifica con textContent y
classList, escucha con addEventListener y habla con el servidor con
fetch + async/await. Hoy todo eso es JavaScript nativo: no necesitas jQuery.
JavaScript es la capa que convierte una página estática en una aplicación. En una arquitectura full stack es además el puente entre lo que ve el usuario y tu backend. En el libro Programación Full-Stack lo usamos para validar formularios, actualizar listas sin recargar y consumir las APIs que construimos con PHP. Aquí tienes lo esencial.
Qué es el DOM
El DOM (Document Object Model) es la representación en memoria de tu HTML: un árbol de objetos que JavaScript puede leer y modificar. Cuando cambias un nodo del DOM, el navegador vuelve a pintar esa parte de la página al instante.
Seleccionar y modificar elementos
// Seleccionar: usa la misma sintaxis que en CSS
const titulo = document.querySelector('h1');
const botones = document.querySelectorAll('.btn'); // NodeList
// Modificar texto (seguro: no interpreta HTML)
titulo.textContent = 'Hola, full stack';
// Clases: mejor que tocar estilos uno a uno
titulo.classList.add('destacado');
titulo.classList.toggle('oculto');
// Atributos
const enlace = document.querySelector('a');
enlace.setAttribute('href', '/contacto');
// Crear e insertar elementos
const item = document.createElement('li');
item.textContent = 'Nuevo elemento';
document.querySelector('#lista').append(item);
innerHTML con datos que vengan del usuario o del servidor: si contienen
<script> o atributos como onerror, abres la puerta a ataques XSS. Usa
textContent o crea los nodos con createElement.
Eventos: reaccionar a lo que hace el usuario
Un evento es algo que ocurre en la página: un clic, una tecla, el envío de un formulario. Se escucha con
addEventListener.
const boton = document.querySelector('#menu-toggle');
const menu = document.querySelector('#menu');
boton.addEventListener('click', () => {
const abierto = menu.classList.toggle('abierto');
boton.setAttribute('aria-expanded', abierto); // accesibilidad
});
// Delegación: un solo listener para muchos elementos,
// incluso los que se agreguen después
document.querySelector('#lista').addEventListener('click', (e) => {
const borrar = e.target.closest('.borrar');
if (!borrar) return;
borrar.closest('li').remove();
});
La delegación de eventos es clave cuando generas filas dinámicamente (por ejemplo, la
tabla de un CRUD): en lugar de añadir un listener por fila, escuchas en el contenedor y miras
e.target.
AJAX moderno con fetch y async/await
AJAX es la técnica de pedir datos al servidor sin recargar la página. Hoy se hace con
fetch, que devuelve una promesa. Con async/await el código se lee de arriba
abajo, como si fuera síncrono.
async function cargarProductos() {
try {
const res = await fetch('api/productos.php');
// fetch NO lanza error con 404 o 500: hay que comprobarlo
if (!res.ok) {
throw new Error(`Error HTTP ${res.status}`);
}
const productos = await res.json();
const lista = document.querySelector('#productos');
lista.replaceChildren(); // vaciar
for (const p of productos) {
const li = document.createElement('li');
li.textContent = `${p.nombre} – $${p.precio}`;
lista.append(li);
}
} catch (error) {
console.error(error);
document.querySelector('#estado').textContent = 'No se pudieron cargar los productos.';
}
}
cargarProductos();
Enviar un formulario sin recargar la página
Este patrón aparece en casi cualquier aplicación: interceptas el submit, envías los datos
con fetch y muestras el resultado.
const form = document.querySelector('#form-contacto');
form.addEventListener('submit', async (e) => {
e.preventDefault(); // evita la recarga
const boton = form.querySelector('button');
boton.disabled = true; // evita envíos dobles
try {
const res = await fetch('contacto.php', {
method: 'POST',
body: new FormData(form) // llega a PHP en $_POST
});
const data = await res.json();
alert(data.mensaje);
form.reset();
} catch {
alert('Error de conexión. Intenta de nuevo.');
} finally {
boton.disabled = false;
}
});
Usar FormData tiene una ventaja enorme: en el servidor, PHP recibe los campos en
$_POST como si fuera un formulario normal. En el
artículo sobre formularios en PHP vemos cómo procesarlos y
validarlos del lado del servidor.
Errores comunes
- Ejecutar el script antes de que exista el HTML: carga tus scripts con
<script src="app.js" defer>o al final delbody. - Creer que
fetchfalla con un 404: solo falla si no hay red. Comprueba siempreres.ok. - Olvidar
await: obtendrás unaPromiseen lugar de los datos. - Validar solo en el navegador: la validación con JavaScript mejora la experiencia, pero cualquiera puede saltársela. El servidor siempre debe validar de nuevo.
Conecta tu frontend con un backend real
En el libro Programación Full-Stack unimos este JavaScript con PHP y MySQL para construir un blog, un sistema de usuarios y una tienda online completos.
Comprar en Amazon