S05 – Atividade de Aprendizagem: localStorage JavaScript
Visão Geral
Há momentos em que o armazenamento de dados não confidenciais proporcionaria uma melhor experiência ao usuário e ofereceria algumas melhorias no desempenho do site. Os mecanismos da API de Armazenamento na Web (Web Storage) fornecem a capacidade de armazenar informações em um formato de chave-valor com base em um agente de usuário ou origem específicos. Nesta atividade, você descobrirá a finalidade e o escopo do mecanismo localStorage disponível por meio da interface Storage. Você usará esse conhecimento para direcionar e exibir alguns dados de tráfego de clientes individuais em uma página.
Os dados de armazenamento na web são salvos em um arquivo SQLite em uma subpasta ou arquivo na pasta de perfil do usuário.
Preparação
Aqui estão alguns dados de comparação entre cookies, localStorage (armazenamento local) e sessionStorage (armazenamento de sessão).
| Cookies | localStorage | sessionStorage | |
|---|---|---|---|
| Capacidade | ~4 KB | ~5 MB | ~5 MB |
| Expira | Definido manualmente | Nunca | Ao fechar aba/janelas |
| Acessível a partir de | Qualquer janela | Qualquer janela | Mesma aba |
Cada um desses métodos armazena dados no cliente do agente do usuário (navegador) real, e não no servidor.
Vantagens do localStorage
- Este método é muito mais intuitivo do que usar o método antigo de Cookies.
- Armazena somente strings em pares de chave-valor.
- Os dados do mecanismo são mantidos sem expirar e ficam disponíveis mesmo quando um agente é fechado e reaberto novamente.
Você pode armazenar dados que não sejam string no localStorage. Uma abordagem comum é usar o método
JSON.stringify() para converter os dados em uma string antes de armazená-los e, então, usar o
método JSON.parse() para convertê-los de volta ao seu formato original quando você recuperá-los do
localStorage. Isso permite que você armazene e recupere estruturas de dados mais complexas, como objetos e
arrays, no localStorage.
Demonstração do localStorage
- Assista: Demonstração do
localStorage – Aqui está o CodePen correspondente usado na demonstração.
Copie (fork) este código para sua conta CodePen e faça testes.
Quais são algumas das diferenças entre armazenamento de sessão e local?
Uma grande diferença é que os dados do localStorage são persistentes (permanecem) mesmo quando a sessão do navegador expira. Já as variáveis de sessão não.
Usando a interface Storage, quais são alguns métodos incorporados a esse objeto de interface e o que eles fazem?
De toda a lista de métodos [key(), getItem(), setItem(), removeItem(), clear()], os mais comuns são getItem() e setItem() que você usará nas tarefas. Interface de Armazenamento da API de Armazenamento na Web
Visão Geral da Atividade
Esta atividade retoma o exercício dos capítulos favoritos do Livro de Mórmon. Os capítulos inseridos pelo usuário não persistem entre as vezes que acessa a aplicação. Em outras palavras, eles não são armazenados em lugar nenhum. Nesta atividade, você usará o localStorage para armazenar a lista de capítulos do Livro de Mórmon para o usuário.
As instruções gerais para esse problema seriam "Aprimorar a aplicação de capítulos favoritos do Livro de Mórmon para que as entradas dos usuários persistam entre os acessos à aplicação usando a API localStorage". Aceite esse desafio pensando primeiro em uma solução para esse problema e depois mapeando-a no papel.
O plano direcionado é criar um array de entradas de livros e capítulos válidas feitas pelo usuário. Então esse array pode ser armazenado no localStorage como uma grande string JSON usando JSON.stringify(). Isso significa que você precisa carregar esse array ao carregar a aplicação com os dados processados do localStorage, SE o componente localStorage nomeado existir. Após o carregamento, você precisará preencher a lista com os valores armazenados.
Então, em vez de ter duas funções que basicamente fazem a mesma coisa, você criará uma única função que anexa a lista de capítulos favoritos com o botão de exclusão correspondente, uma vez no carregamento e também quando uma nova entrada é feita.
Instruções da Atividade
- Faça uma cópia da sua aplicação do Livro de Mórmon, copiando o HTML, CSS e JavaScript da atividade de aprendizagem anterior para uma pasta chamada semana05.
- Abra o arquivo JavaScript. Declare um array chamado
arrayCapitulose atribua-o aos resultados de uma função definida chamadaobterListaDeCapitulos(Esta função não existe ainda). - Na mesma declaração e atribuição de variável de array, adicione uma condição OR composta para atribuir a ela
um array vazio, caso este seja o primeiro acesso do usuário ou se o item localStorage estiver ausente.
Isso funciona porque a função pode não retornar nada, então é falsa, ou seja, ela voltará a atribuir o array vazio a
arrayCapitulos.Exemplo
const input = document.querySelector('#capfav'); const botao = document.querySelector('#botao'); const lista = document.querySelector('#lista'); let arrayCapitulos = obterListaDeCapitulos() || [];Explicações do CódigoAs três primeiras linhas estabelecem referências aos elementos DOM que você usará no programa. Observe que elas fazem referência apenas aos objetos do elemento HTML, não a nenhuma propriedade.
A declaração de array inicializa a variável arrayCapitulos com a lista de capítulos retornados pela função obterListaDeCapitulos() ou um array vazio se a chamada de função retornar null (nulo) ou undefined (indefinido).
- Agora preencha a lista de capítulos exibida. Use
forEachnoarrayCapitulospara processar cada entrada chamadacapitulo. Use uma função de seta dentro do loop para chamar uma nova função definida chamadaexibirListae passar a ela o argumento docapitulo. Dessa forma, cada entrada será processada (ou seja, anexada à lista).Exemplo
arrayCapitulos.forEach(capitulo=> { exibirLista(capitulo); }); - Altere o ouvinte de evento de clique de botão para executar apenas as seguintes tarefas (as outras tarefas na
função original serão usadas em uma função separada chamada
exibirLista):- Verifique se a entrada está vazia; se não estiver, então...
- Chame
exibirListacom o argumentoinput.value - Faça push no
input.valuepara oarrayCapitulos - Atualize o localStorage com o novo array chamando uma função denominada
definirListaDeCapitulos - Defina o
input.valuecomo nada - Retorne o foco para a entrada.
Exemplo com // comentários de código
button.addEventListener('click', () => { if (input.value != '') { // certifique-se de que a entrada não esteja vazia exibirLista(input.value); // chama a função que gera o capítulo enviado arrayCapitulos.push(input.value); // adicione o capítulo ao array definirListaDeCapitulos(); // atualize o localStorage com o novo array input.value = ''; // limpe a entrada input.focus(); // defina o foco de volta para a entrada } }); - Crie a função definida
exibirListaque recebe um parâmetro chamadoitem. - Coloque todo o código que cria um item de lista do ouvinte de evento de clique de botão anterior nesta nova
função
exibirListae use o parâmetroitemcomo entrada. Uma funçãoexcluirCapituloprecisará ser chamada dentro do evento de clique do botão "delete" para remover o capítulo do array e do localStorage.Exemplo:
exibirLista()function exibirLista(item) { let li = document.createElement('li'); let botaoExcluir = document.createElement('button'); li.textContent = item; // observe o uso do 'item' do parâmetro exibirLista botaoExcluir.textContent = '❌'; botaoExcluir.classList.add('delete'); // isso faz referência à regra CSS .delete{width:fit-content;} para dimensionar o botão de exclusão li.append(botaoExcluir); list.append(li); botaoExcluir.addEventListener('click', function () { list.removeChild(li); excluirCapitulo(li.textContent); // observe esta nova função que é necessária para remover o capítulo do array e do localStorage. input.focus(); // defina o foco de volta para a entrada }); console.log('Eu gosto de copiar código em vez de digitá-lo e tentar entendê-lo.'); } - Defina a função
definirListaDeCapitulospara definir o item de localStorage que você já nomeou. UseJSON.stringify()para transformar o array em string.Exemplo:
definirListaDeCapitulos()function definirListaDeCapitulos() { localStorage.setItem('minhaListaFavoritosLDM', JSON.stringify(arrayCapitulos)); } - Defina a função
obterListaDeCapitulospara obter o item de localStorage. Nenhum parâmetro é necessário. Como essa função retorna para um array em espera, você precisará usarJSON.parsena string.Exemplo:
obterListaDeCapitulos()function obterListaDeCapitulos() { return JSON.parse(localStorage.getItem('minhaListaFavoritosLDM')); } - Por fim, defina a função
excluirCapitulocom um parâmetro chamadocapituloque faz três coisas.- Reformate o parâmetro
capitulopara se livrar ❌ do que é processado no final da string do capítulo quando você chama a funçãoexcluirCapitulo. Use o método string.slice() para extrair o último caractere.capitulo = capitulo.slice(0, capitulo.length – 1); // isso corta o último caractere - Redefina o array
arrayCapitulosusando o método array.filter para retornar tudo, exceto o capítulo a ser removido.arrayCapitulos = arrayCapitulos.filter((item) => item !== capitulo); - Chame a função
definirListaDeCapitulospara atualizar o item de localStorage.
Exemplo:
excluirCapitulo()function excluirCapitulo(capitulo) { capitulo = capitulo.slice(0, capitulo.length – 1); arrayCapitulos = arrayCapitulos.filter(item => item !== capitulo); definirListaDeCapitulos(); } - Reformate o parâmetro
Teste
Teste a aplicação adicionando e excluindo capítulos. Faça uma atualização completa, esvazie o cache e veja se os capítulos persistem. Você também pode apagar todo o conteúdo do localStorage da aplicação na aba Applications (Aplicações) no DevTools.
Recursos Opcionais
- Vídeo: WebStorage, localStorage e SessionStorage em Javascript – YouTube
- Vídeo: Aprenda a Criar e Manipular Cookies com JavaScript – YouTube
- Uma abordagem dinâmica e estruturada para essa atividade seria usar o Set objeto em JavaScript. Set nos permite adicionar e excluir itens do objeto Set conforme necessário.
- Referência: API de Armazenamento na Web – MDN
- A API IndexedDB é um método mais robusto de armazenamento de dados no lado do cliente e é mais parecida com um banco de dados.
- A API Cache é um método de armazenamento de dados usado especificamente para armazenar dados em cache para uso offline.