Blog fellyph cintra - localstorage banner

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á para 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 recurso voltou a ficar evidência.

LocalStorage

Ela permite o armazenamento de strings com chave e valor é 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 mais 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:

tipos de armazenamento
tipos de armazenamento

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");Code language: JavaScript (javascript)

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.

Como visualizar os dados do LocalStorage?

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 à aba Application, na sessão storage vemos a opções disponíveis. Quando clicamos em Local Storage vemos as aplicações separadas por URL, no meu teste, estou rodando em localhost, clicando no URL da nossa aplicação, vemos os dados armazenados:

Visualizando dados do localstorage
Visualizando dados do localstorage

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);
Code language: JavaScript (javascript)

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 alerta para exibir a informação.

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

localStorage.removeItem('key_da_propriedade');
Code language: JavaScript (javascript)

Aplicando localStorage, na prática

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>
Code language: HTML, XML (xml)

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';	
			}
		});
Code language: JavaScript (javascript)

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 no nosso localStorage. Esse exemplo não é muito funcional apenas exemplifica como é salvar um objeto no 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ó dá 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>
Code language: HTML, XML (xml)

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;
}
Code language: CSS (css)

Detalhe para o último 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);
});

Code language: JavaScript (javascript)

Tentei comentar os pontos mais importantes do código, na listagem utilizo um map para montar a 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 as suas 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.


Publicado

em

, ,

por

Comentários

4 respostas para “localStorage: Armazenando dados com JavaScript”

  1. Avatar de Wesley
    Wesley

    porque que no começo das funções whatsYourName é sayMyName e colocado document.body.innerHTML = ‘ ‘? é muinto obrigado já me deu uma ajuda

    1. Avatar de Fellyph Cintra
      Fellyph Cintra

      Olá Wesley, boa pergunta. No caso essa atribuição é para simplesmente para limpar o conteúdo anterior salvo no body. Mas isso só por conta da função appendChild, ele não substitui o conteúdo anterior só adicionar conteúdo ao final do texto.

  2. Avatar de izaias de oliveira elias
    izaias de oliveira elias

    Bom dia.
    Eu estou criando um site de notas com alerta de tempo de tarefa e estou tendouitos problemas com pouco conhecimento, vc poderia me ajudar?.
    Ótimo artigo.

  3. Avatar de Lucas
    Lucas

    Salvou aqui mano, ajudou muito – Agradeço d+

Deixe um comentário

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