Categorias
HTML5 JavaScript Tutoriais

localStorage: Armazenando dados com JavaScript

Esse post é um dos posts mais visualizados do blog, foi criado em 2013 mas vou dar uma atualizada no que aconteceu de lá pra cá. Armazenamento local com localStorage é umas das features mais úteis do HTML5 podemos utilizar para uma infinidade de ações agora com Progressive Web Apps esse recursos voltou a ficar evidência.

Ela permite o armazenamento de strings com chave e valor e considerado cookies é uma forma mais segura de armazenamento, mas ela não tem acesso através de Service Worker. Mas é um recurso nativo no browser de implementação simples que não necessita de plugin ou library externa.

Para aplicações mas complexas temos a opção de utilizar o IndexedDB. Mas um dos pontos fortes do localStorage é o suporte comparado a outras APIs ele é suportado por 93% dos browsers:

LocalStorage é um dos recursos do DOM Storage com ele podemos armazenar dados apenas em formato de texto, mas claro podemos contornar essa limitação. Vamos primeiro exemplo básico de armazenamento.

localStorage.setItem("key_da_propriedade","Valor armazenado");

No código acima adicionamos uma variável com nome “key_da_propriedade” que irá armazenar “Valor armazenado”. Quando esse código for armazenado pelo browser o usuário pode sair da aplicação, continuar navegando em outras aplicações quando ele voltar para nossa aplicação o dado continuará lá. Esse recurso será útil caso utilizarmos uma versão offline de nossa aplicação com PWA.

Para visualizar a informação que foi salva, no Google Chrome para abrir o developer Tools vamos em “menu > View > developer > developer tools”, tecla de atalho ctrl+shift+i ou simples clique o com botão direito do mouse e selecionamos a opção “inspect”, com developer tools aberto vamos na aba Application, na sessão storage vemos a opções disponíveis. Quando clicamos em Local Storage vemos as aplicações separadas por url, meu teste estou rodando em localhost, clicando na url da nossa aplicação vemos os dados armazenados:

Agora que sabemos que a informação foi salva vamos resgatar esse valor com o seguinte código:

const minha_propriedade = localStorage.getItem('key_da_propriedade'); alert("Valor:" + minha_propriedade);

No código acima passamos a função getItem e como parâmetro passamos a key da informação que queremos resgatar, na linha seguinte apenas executamos um alert para exibir a informação.

Caso queria remover essa informação do localStorage utilizamos o seguinte código:

localStorage.removeItem('key_da_propriedade');

Agora vamos para um exemplo prático aplicando essas três funções que virmos acima, no caso: salvar, ler e excluir os dados no localStorage.

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>LocalStorage tutorial</title> <script> window.addEventListener('load',() => { if(localStorage.getItem('name')){ sayMyName() }else{ whatsYourName() } }); function whatsYourName(){ document.body.innerHTML = ''; // criando um input para cadastrar o nome; const inputName = document.createElement('input'); inputName.type = 'text'; inputName.placeholder = 'Digite seu nome'; inputName.id = 'nome'; document.body.appendChild(inputName); // criando saveButton const saveButton = document.createElement('button'); saveButton.innerHTML = 'Salvar'; document.body.appendChild(saveButton); // adicionando listener para salvar a informação saveButton.addEventListener('click', saveName); } function sayMyName(){ document.body.innerHTML = ''; // criando mensagem const welcomeMessage = document.createElement('h1'); welcomeMessage.innerText = 'Olá' + localStorage.getItem("name"); // criando removeButton const removeButton = document.createElement('button'); removeButton.innerHTML = 'Excluir'; document.body.appendChild(removeButton); // adicionando o listener para remover informação removeButton.addEventListener('click',removeName); } function removeName(){ if(localStorage.getItem('name')){ localStorage.removeItem('name'); whatsYourName() } } function saveName(){ var nome = document.getElementById('nome').value; localStorage.setItem('name', nome) sayMyName(); } </script> </head> <body> </body> </html>

O Exemplo acima resumindo rapidamente ele verifica se tem o dado com a key “name” no localStorage, caso tenha, exibe o nome. Caso contrário adiciona um input para cadastrar o dado. Quando o nome é exibido também adicionamos um button para chamar a função de excluir os dados. Nos Exemplos anteriores apenas adicionamos e removemos algumas strings, para trabalhar com objetos no localStorage precisamos usar a Classe JSON, com ela é possível fazer a ponte entre textos e objetos.

window.addEventListener('load',() => { if(localStorage.getItem('user')){ const texto = localStorage.getItem("user"); const objeto = JSON.parse(texto); document.body.innerHTML = `nome: <strong>${objeto.name}</strong> email: <strong>${objeto.email}<strong>`; }else{ const user = { name: 'Fellyph', email: 'fellyph@fellyph.com.br' } const userString = JSON.stringify(user); localStorage.setItem('user',userString); document.body.innerHTML = 'dados salvos'; } });

No código acima focamos apenas no javaScript, verificamos se existe um dado com uma key “user”, caso exista ele resgata a informação na variável “texto” em seguida convertemos o texto em objeto utilizando a método parse da classe JSON, assim temos um objeto como retorno e adicionamos o conteúdo no body do nosso arquivo, no código acima utilizamos string literals para concatenar o nosso conteúdo.

Caso o usuário não tenha nenhuma informação salva com a key “user”, o código irá criar um objeto e em seguida converter em texto, assim temos a possibilidade de salvar os dados no em nosso localStorage. Esse exemplo não é muito funcional apenas exemplifica como é salvar um objeto em nosso localStorage.

Agora vamos partir para um exemplo mais funcional, vamos montar uma todo-list utilizando localStorage, desta vez vamos separar o código no arquivo todo-list.html, js/app.js e css/style.css. O exemplo a seguir utiliza ES2015 caso queira dar uma olhada no exemplo em EcmaScript 5 só da uma olhada no gitHub no seguinte link: https://github.com/fellyph/Tutorial-bbUI/tree/master/localstorage

Nosso HTML:

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Todo List</title> <link rel="stylesheet" href="css/style.css"> <script src="js/app.js"></script> </head> <body> <h1>todo-list</h1> <div id="tasks-output"></div> <form id="form-task"> <input type="text" name="descricao" placeholder="adicione uma nova task" required> <input type="submit" value="Salvar"> </form> </body> </html>

Nosso CSS:

#tasks-output li { cursor: pointer; } #form-task { border-top: 1px solid #ddd; padding: 10px 0; margin: 10px 0; } #tasks-output li[data-done="true"] { text-decoration: line-through; }

Detalhe para o ultimo seletor que trata quando o item da lista possui o atributo data-done igual a true, ele vai adicionar uma linha sobre o texto.

let todoList; let todoOutput; function formatDate(date) { // formata a data para o formato DD/MM/YYYY const time = new Date(date); return `${time.getDate()}/${time.getMonth()}/${time.getFullYear()}`; } function showList() { // mostra a lista de todo if (todoList.length > 0) { const htmlTemp = `<ul> ${todoList.map(todoItem => `<li data-id="${todoItem.id}" data-done="${todoItem.done}">${todoItem.descricao} - ${formatDate(todoItem.date)}</li>` )} </ul><button>Limpar tarefas realizadas</button>`; todoOutput.innerHTML = htmlTemp; } else { todoOutput.innerHTML = 'Nenhuma tarefa cadastrada'; } } function saveList() { // converte os dados em string e salva no local storage localStorage.setItem('tasks', JSON.stringify(todoList)); } function clearList() { // varre a lista a procura de tarefas realizadas for (let i = 0; i < todoList.length; i += 1) { if (todoList[i].done === 'true') { // remove 1 elemento na posição i; todoList.splice(i, 1); // voltando o indice no array para validar novamente a lista i = 0; } else { todoList[i].id = i; } } showList(); saveList(); } function clickList(e) { // somente fazer algo quando clicar em um item li if (e.target.localName === 'li') { e.target.dataset.done = !e.target.dataset.done === 'true'; todoList[e.target.dataset.id].done = e.target.dataset.done; saveList(); } else if (e.target.localName === 'button') { clearList(); } } function onSubmit(e) { const task = {}; // pego o valor cadastrado no primeiro input do meu form task.descricao = e.target[0].value; task.date = new Date(); task.id = todoList.length; task.done = 'false'; // adicionando a task na lista todoList.push(task); saveList(); showList(); // utiliza o preventDefault para evitar do form realizar o reload da página e.preventDefault(); } window.addEventListener('load', () => { // guarda em uma variável o elemento tasks-output todoOutput = document.getElementById('tasks-output'); if (localStorage.getItem('tasks')) { todoList = JSON.parse(localStorage.getItem('tasks')); showList(); } else { todoList = []; } if (todoList.length === 0) { todoOutput.innerHTML = 'Nenhuma tarefa cadastrada'; } // adiciona o listener para o evento submit, utilizei form para usar o required do input HTML document.getElementById('form-task').addEventListener('submit', onSubmit); todoOutput.addEventListener('click', clickList); });

Tentei comentar os pontos mais importantes do código, na listagem utilizo um map para montar nossa lista caso não esteja familiarizado só conferir a versão anterior desse código no git ou conferir os posts relacioanos a ecmaScript 2015, mas o código acima o usuário pode cadastrar as tasks que serão vinculadas uma data, quando o usuário clica no item da lista a propriedade “data-done” muda entre true ou false. caso o usuário queira limpar sua listas de task clica no botão “Limpar tarefas…” o código irá varrer da lista os itens com valor da propriedade data-done igual a true e retirar da lista.

Além do LocalStorage temos o SessionStorage, a diferença entre os dois é que o sessionStorage como o nome sugere ele guarda as informações apenas na seção ou seja, quando o aplicação é finalizada a informação é removida.

Fechamos por aqui e até o próximo tutorial, para saber mais como acessar recursos do device confira a página da categoria PWA.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *