Engenharia Estrutural Civil &
Criando um Gerenciador de Favoritos Javascript com Persistência de Armazenamento Local
Table of Contents
Compreender os princípios básicos
Construir um gerenciador de favoritos com JavaScript e a API de armazenamento web é um excelente projeto para dominar conceitos fundamentais de front-end. No seu núcleo, a aplicação deve lidar com três operações primárias: criar, ler, e deletar[ — um padrão clássico CRUD, menos atualizações por enquanto. Os dados vivem no navegador []localStorage[[, permitindo que os favoritos persistam em sessões sem servidor.
Antes de escrever uma única linha de código, solidifique sua compreensão dos seguintes pilares:
- A API DOM: Você irá consultar elementos, ouvir eventos e manipular a árvore de documentos para exibir os favoritos dinamicamente.
- localStorage:] Esta loja de valor chave retém dados mesmo após o navegador estar fechado. Só suporta strings, por isso os objetos devem ser serializados com e deserializados com .
- Programação orientada para eventos: Os formulários emitem eventos; apagar botões disparam eventos. Dominar não é negociável.
- Métodos de array: , , e ajudarão a renderizar e manipular a lista de favoritos de forma eficiente.
Construindo o Gerenciador de Favoritos do Núcleo
Estrutura HTML
Comece com um esqueleto HTML semântico mínimo. O formulário recolhe o nome e URL do favorito; uma lista não ordenada mostra os favoritos armazenados.
<!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 o atributo na tag do script – garante que o DOM seja analisado totalmente antes de o script ser executado, eliminando a necessidade de um envoltório em configurações modernas.
Estilhaço para usabilidade (Opcional, mas Recomendado)
Embora o CSS não seja o foco, uma interface limpa melhora a experiência do usuário. Adicione uma folha de estilo simples para espaçar o formulário, dê uma aparência consistente aos botões e estile os itens da lista de favoritos com efeitos de hover. O estilo inline mínimo também pode ser injetado via JavaScript, mas uma opção separada é preferida para manutenção.
<!-- inside <head> -->
<link rel="stylesheet" href="style.css" />
Em , use flexbox para o layout do formulário, uma largura máxima para o recipiente e feedback visual distinto para excluir botões para evitar cliques acidentais.
Lógica JavaScript – O Coração da Aplicação
Toda a persistência e interatividade vivem em . As seções seguintes quebram cada função.
Inicialização dos Dados
Precisamos de uma variável central que mantenha a lista atual de favoritos. Ela deve ser inicializada de ou voltar para um array vazio.
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();
A função é chamada sempre que o array muda — após adicionar, editar ou excluir um marcador. Isto garante que o armazenamento esteja sempre sincronizado com o array in-memory.
Mostrar Favoritos
Renderizar a lista de favoritos significa iterar sobre o array e criar itens de lista com uma marca âncora e um botão de exclusão.
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);
});
}
Usando em vez de innerHTML evita vulnerabilidades XSS quando os nomes dos favoritos contêm HTML. O botão excluir usa um fechamento para capturar o índice do marcador.
Adicionar um Marcador
Ouça o evento , evite o reload da página padrão, crie um objeto de favoritos, empurre-o para o array, persista e 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();
});
Esta abordagem é simples. Para a produção, você pode querer validar o formato URL ainda mais usando construtor ou um regex.
Excluindo um marcador
A exclusão remove o item no índice e atualiza o armazenamento e o DOM.
function deleteBookmark(index) {
bookmarks.splice(index, 1);
saveBookmarks();
renderBookmarks();
}
Usando muda o array no lugar. Se você preferir imutabilidade, você pode usar e reatribuir , mas para um pequeno projeto como este, é claro e performante.
Melhorar a Aplicação
Uma vez que o CRUD básico funcione, considere essas melhorias para transformar um protótipo em uma ferramenta robusta.
Editar Favoritos
Substituir o nome/link estático por um modo de edição em linha. Quando o usuário clicar em um botão de edição, troque a etiqueta âncora com os campos de entrada pré- preenchidos com os valores atuais. Ao salvar, atualize o array e persista.
Dica de implementação: adicione uma função que cria entradas editáveis. Use delegação de eventos na lista para lidar com salvar edições sem anexar vários ouvintes.
Categorização com etiquetas
Adicione uma propriedade opcional a cada objeto de favoritos (por exemplo, ]). Então, estenda a interface com uma entrada de filtro que esconde itens de lista cujas etiquetas não correspondem. Você pode armazenar tags como uma string separada por vírgulas dentro do formulário e dividi-las em um array.
Importação e Exportação
Permitir que os usuários façam backup ou transfiram os favoritos. Use um ou um download de arquivo. Exportar serializa em uma string JSON e ativa um download via ] e . Importar lê o JSON e se funde com os favoritos 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);
}
Procurar e Filtrar
Adicionar uma entrada acima da lista de favoritos. Em cada evento , filtre o array pelo nome (ou URL) e chame uma variante de que exibe apenas as correspondências. Para evitar perder a lista original, guarde uma cópia filtrada ou use um parâmetro calculado.
Compatibilidade com o Teste e o Navegador
O armazenamento local é suportado em todos os navegadores modernos, mas versões mais antigas do Internet Explorer (IE 8+) tinham uma API diferente. Se você deve suportar ambientes legados, teste com polifills ou voltar para cookies. Hoje Chrome, Firefox, Safari, Edge (tanto Chromium quanto legado) manusear ] e ] sem problemas.
Ao testar, verifique:
- Os dados sobrevivem às atualizações da página e o navegador reinicia.
- Excluindo um favorito atualiza tanto a UI quanto o armazenamento.
- Os caracteres especiais em nomes de favoritos (quotas, ampersands) são renderizados corretamente.
- URLs com e sem são normalizadas.
Use as ferramentas de desenvolvimento [[FLT: 0][[FLT: 1]] & gt; Aplicação & gt; Armazenamento Local & gt; para inspecionar os dados salvos manualmente.[[ FLT: 2]] Para testes automatizados, considere usar [[ FLT: 3]] Cypress [[ FLT: 4]] ou [[ FLT: 5] Playwright[[[[ FLT: 6]] para simular fluxos de trabalho do usuário — preencher o formulário, adicionar, excluir, recarregar — e afirmar que a lista persiste.
Conclusão
Este projeto demonstra como algumas dezenas de linhas de baunilha JavaScript pode criar uma aplicação web totalmente funcional e persistente. Você aprendeu a aproveitar a localStorage API para persistência de dados, ] delegação de eventos[ para atualizações de UI eficientes, e operações CRUD[] sem uma infraestrutura. O padrão que você aplicou — inicializando estado de armazenamento, mutando estado através de funções, e re-renderizando o DOM — é a base de muitos frameworks de front-end modernos como React ou Vue.
Para aprofundar a sua compreensão, explore a documentação MDN sobre o armazenamento local e leia sobre ] o tratamento de eventos no DOM. Para uma gestão mais avançada do estado, consulte IndexedDB[] para conjuntos de dados maiores ou trabalhadores de serviços[[]] para experiências offline. Com estes blocos de construção, você pode agora expandir o seu gerenciador de favoritos para uma base de conhecimento pessoal completa.