Volver a JavaScript Intermedio
JavaScript
JavaScript Intermedio
Web APIs y Almacenamiento en el Navegador
Los navegadores modernos exponen APIs integradas muy potentes. Este capítulo cubre las más útiles para construir aplicaciones reales.
Fetch API
// GET básico
const response = await fetch('/api/usuarios');
const usuarios = await response.json();
// POST con cuerpo JSON
const nuevoUsuario = await fetch('/api/usuarios', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nombre: 'Ana', rol: 'admin' }),
}).then(r => r.json());
// Wrapper robusto de fetch
async function apiFetch(url, opciones = {}) {
const response = await fetch(url, {
headers: { 'Content-Type': 'application/json', ...opciones.headers },
...opciones,
});
if (!response.ok) {
const error = await response.json().catch(() => ({ message: response.statusText }));
throw new Error(error.message ?? `HTTP ${response.status}`);
}
return response.status === 204 ? null : response.json();
}
Almacenamiento en el Navegador
// localStorage — persiste entre sesiones
localStorage.setItem('tema', 'oscuro');
const tema = localStorage.getItem('tema'); // 'oscuro'
localStorage.removeItem('tema');
localStorage.clear();
// Guardar objetos (hay que serializar)
const preferencias = { tema: 'oscuro', fuente: 16 };
localStorage.setItem('prefs', JSON.stringify(preferencias));
const cargadas = JSON.parse(localStorage.getItem('prefs') ?? '{}');
// sessionStorage — se borra al cerrar la pestaña
sessionStorage.setItem('tokenTemporal', 'abc123');
| localStorage | sessionStorage | Cookies | |
|---|---|---|---|
| Capacidad | ~5 MB | ~5 MB | ~4 KB |
| Persiste | Para siempre | Sesión de pestaña | Configurable |
| Se envía al servidor | ❌ | ❌ | ✅ |
Intersection Observer
Detecta cuando los elementos entran/salen del viewport (carga diferida, scroll infinito, animaciones):
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
// Opcionalmente dejar de observar tras la primera aparición
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.1 } // 10% visible activa el callback
);
document.querySelectorAll('.animar-al-aparecer').forEach(el => observer.observe(el));
Web Workers
Ejecuta código costoso en CPU fuera del hilo principal para mantener la UI fluida:
// worker.js
self.onmessage = function ({ data }) {
// Cálculo costoso
const resultado = data.reduce((suma, n) => suma + n, 0);
self.postMessage(resultado);
};
// main.js
const worker = new Worker('worker.js');
worker.postMessage([1, 2, 3, 4, 5]);
worker.onmessage = ({ data }) => {
console.log('Suma:', data); // Suma: 15
worker.terminate();
};
URL y URLSearchParams
const url = new URL('https://ejemplo.com/buscar?q=js&pagina=2');
url.hostname; // 'ejemplo.com'
url.pathname; // '/buscar'
url.searchParams.get('q'); // 'js'
url.searchParams.get('pagina'); // '2'
// Construir query strings de forma segura (maneja codificación)
const params = new URLSearchParams({ q: 'hola mundo', pagina: 1 });
params.toString(); // 'q=hola+mundo&pagina=1'
API del Portapapeles
// Escribir
await navigator.clipboard.writeText('¡Texto copiado!');
// Leer
const texto = await navigator.clipboard.readText();
// Botón de copiar práctico
async function copiarAlPortapapeles(texto) {
try {
await navigator.clipboard.writeText(texto);
return true;
} catch {
// Fallback para navegadores más antiguos
const el = document.createElement('textarea');
el.value = texto;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
return true;
}
}