Comprender las bases

Construir un gestor de marcadores con JavaScript y la API de almacenamiento web es un excelente proyecto para dominar conceptos fundamentales de vanguardia. En su núcleo, la aplicación debe manejar tres operaciones primarias: crear, read, y — un patrón clásico de actualizaciones de minus

Antes de escribir una sola línea de código, solidifique su comprensión de los siguientes pilares:

  • La API DOM: Usted preguntará elementos, escuchará eventos y manipulará el árbol de documentos para mostrar marcadores dinámicamente.
  • localStorage: Esta tienda de valor clave conserva datos incluso después de que el navegador esté cerrado. Sólo admite cadenas, por lo que los objetos deben ser serializados con y deserializados con .
  • Programación impulsada por el evento: Los formularios emiten eventos; borrar botones fuego eventos. Dominar no es negociable.
  • Métodos de rayos: , , y ayudará a renderizar y manipular la lista de marcadores de manera eficiente.

Construyendo el Core Bookmark Manager

Estructura HTML

Comience con un esqueleto HTML mínimo y semántico. El formulario recoge el nombre y la URL del marcador; una lista sin orden hace los marcadores almacenados.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Bookmark Manager</title>
</head>
<body>
 <h1>My Bookmarks</h1>
 <form id="bookmarkForm">
 <label for="name">Name</label>
 <input type="text" id="name" required />
 <label for="url">URL</label>
 <input type="url" id="url" required />
 <button type="submit">Add Bookmark</button>
 </form>
 <ul id="bookmarkList"></ul>
 <script src="app.js" defer></script>
</body>
</html>

Observe el atributo en la etiqueta script—se asegura que el DOM se analiza completamente antes de que el script funcione, eliminando la necesidad de un envoltorio en configuraciones modernas.

Estilismo para la usabilidad (Opcional pero Recomendado)

Aunque CSS no es el foco, una interfaz limpia mejora la experiencia del usuario. Agregue una hoja de estilo simple para espaciar el formulario, dé a los botones un aspecto consistente, y estilo los elementos de lista de marcadores con efectos de arrastre. El estilo de inline mínimo también se puede inyectar a través de JavaScript, pero un separado es preferido para la mantenibilidad.

<!-- inside <head> -->
<link rel="stylesheet" href="style.css" />

En , utilice flexbox para el diseño de formularios, una anchura máxima para el contenedor, y una retroalimentación visual distinta para eliminar botones para evitar clics accidentales.

Logic de JavaScript – El corazón de la aplicación

Toda la persistencia e interactividad viven en . Las siguientes secciones descomponen cada función.

Iniciación de datos

Necesitamos una variable central que contenga la lista actual de marcadores. Debe ser inicializada de ] o caer de nuevo a un array vacío.

let bookmarks = [];

function loadBookmarks() {
 const stored = localStorage.getItem('bookmarks');
 if (stored) {
 bookmarks = JSON.parse(stored);
 } else {
 bookmarks = [];
 }
}

function saveBookmarks() {
 localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}

loadBookmarks();

La función se llama cada vez que el array cambia — después de añadir, editar o borrar un marcador. Esto asegura que el almacenamiento siempre se sincroniza con el array en memoria.

Mostrando marcadores

Rendering the bookmark list means iterating over the array and creating list items with an anchor tag and a delete button.

function renderBookmarks() {
 const list = document.getElementById('bookmarkList');
 list.innerHTML = ''; // clear existing entries

 bookmarks.forEach(function(bookmark, index) {
 const li = document.createElement('li');
 li.dataset.index = index;

 const link = document.createElement('a');
 link.href = bookmark.url;
 link.textContent = bookmark.name;
 link.target = '_blank';
 link.rel = 'noopener noreferrer';

 const deleteBtn = document.createElement('button');
 deleteBtn.textContent = 'Delete';
 deleteBtn.addEventListener('click', function() {
 deleteBookmark(index);
 });

 li.appendChild(link);
 li.appendChild(deleteBtn);
 list.appendChild(li);
 });
}

Utilizando en lugar de interiorHTML evita vulnerabilidades XSS cuando los nombres de marcadores contienen HTML. El botón de eliminación utiliza un cierre para capturar el índice de marcador.

Agregar un marcador

Escuche el evento del formulario, prevenga la recarga de la página predeterminada, cree un objeto marcador, presione el array, persista y re-render.

document.getElementById('bookmarkForm').addEventListener('submit', function(e) {
 e.preventDefault();

 const nameInput = document.getElementById('name');
 const urlInput = document.getElementById('url');

 const newBookmark = {
 name: nameInput.value.trim(),
 url: urlInput.value.trim()
 };

 // Basic validation: ensure URL starts with http/https
 if (!newBookmark.url.startsWith('http://') && !newBookmark.url.startsWith('https://')) {
 newBookmark.url = 'https://' + newBookmark.url;
 }

 bookmarks.push(newBookmark);
 saveBookmarks();
 renderBookmarks();

 // Reset form
 nameInput.value = '';
 urlInput.value = '';
 nameInput.focus();
});

Este enfoque es sencillo. Para la producción, es posible que desee validar el formato URL más adelante utilizando constructor o un reex.

Eliminar un marcador

La eliminación elimina el artículo en el índice dado y actualiza el almacenamiento y el DOM.

function deleteBookmark(index) {
 bookmarks.splice(index, 1);
 saveBookmarks();
 renderBookmarks();
}

Usando muta el array en su lugar. Si prefiere la inmutabilidad, puede utilizar y reasignar , pero para un pequeño proyecto como este, es claro y performant.

Mejora de la aplicación

Una vez que el CRUD básico funciona, considere estas mejoras para convertir un prototipo en una herramienta robusta.

Edición de marcadores

Reemplazar el nombre estático/link con un modo de edición en línea. Cuando el usuario haga clic en un botón de edición, cambiar la etiqueta del ancla con campos de entrada pre-llenados con los valores actuales. En guardar, actualizar el array y persistir.

Insinuación de la implementación: añadir una función que crea insumos editables. Usar delegación deeventos en la lista para manejar los ahorros de edición sin adjuntar a múltiples oyentes.

Categorización con Etiquetas

Agregue una propiedad opcional a cada objeto marcador (por ejemplo, ). Luego, extienda la interfaz de usuario con una entrada de filtro que oculta los elementos de lista cuyas etiquetas no coinciden. Puede almacenar etiquetas como una cadena separada por coma dentro del formulario y dividirlos en un array.

Importación y exportación

Permitir a los usuarios copia de seguridad o transferir marcadores. Utilice un o una descarga de archivos. Exportar serializa en una cadena JSON y activa una descarga a través de y ]. Importa lee el JSON y se fusiona con los marcadores existentes.

function exportBookmarks() {
 const data = JSON.stringify(bookmarks, null, 2);
 const blob = new Blob([data], { type: 'application/json' });
 const url = URL.createObjectURL(blob);
 const a = document.createElement('a');
 a.href = url;
 a.download = 'bookmarks.json';
 a.click();
 URL.revokeObjectURL(url);
}

Búsqueda y Filtro

Agregue una entrada por encima de la lista de marcadores. En cada evento , filtra la matriz por nombre (o URL) y llama a una variante de que muestra sólo los partidos. Para evitar perder la lista original, almacena una copia filtrada o utiliza un parámetro computado.

Testing y compatibilidad del navegador

localStorage es compatible con todos los navegadores modernos, pero versiones anteriores de Internet Explorer (IE 8+) tenían una API diferente. Si usted debe apoyar entornos heredados, probar con polifilles o caer de nuevo a las cookies. Hoy ]Chrome, Firefox, Safari, Edge (tanto cromo como legado) mango y [[FLT]

Cuando se prueba, verifique:

  • Los datos sobreviven a las actualizaciones de la página y el navegador se reinicia.
  • Eliminar una marca de marca actualizaciones tanto la interfaz de usuario como el almacenamiento.
  • Los caracteres especiales en nombres de marcadores (cotillas, ampersands) se muestran correctamente.
  • Las URL con y sin se normalizan.

Use herramientas de desarrollo] > Aplicación > Almacenamiento local para inspeccionar los datos guardados manualmente.
Para las pruebas automatizadas, considere usar Cipress o Playwright afirma que la lista de trabajo de los usuarios sigue siendo posible.

Conclusión

Este proyecto demuestra cómo unas pocas docenas de líneas de vainilla Puede crear una aplicación web totalmente funcional y persistente. Ha aprendido a aprovechar la API de almacenamiento local para la persistencia de datos, delegación de eventos] para actualizaciones eficientes de interfaz de usuario, y operaciones de usuario

Para profundizar su comprensión, explore la documentación de MDN en el almacenamiento local] y lea sobre manejo deeventos en el DOM. Para una gestión más avanzada del estado, busque IndexedDB] para conjuntos de datos más grandes o [FLT[6] trabajadores de servicio fuera de línea]