Bom dia amigosNeste artigo, veremos alguns exemplos de uso da API de armazenamento na Web ou do objeto Storage.O que exatamente vamos fazer?- Aprenda a lembrar o tempo de reprodução do vídeo.
- Trabalharemos com o formulário de login da página.
- Vamos escrever a lógica da lista de tarefas.
- Implementamos bate-papo.
- Esboce uma cesta de mercadorias.
Então vamos.Breve revisão
O objeto Storage é usado para armazenar dados no lado do cliente e, nesse sentido, atua como uma alternativa aos cookies. A vantagem do armazenamento é o tamanho do armazenamento (a partir de 5 MB, depende do navegador, quando o limite é excedido, o erro "QUOTA_EXCEEDED_ERR" é gerado) e não há necessidade de acessar o servidor. Uma desvantagem significativa é a segurança: custa um script mal-intencionado para acessar a página e a gravação é perdida. Portanto, é altamente desencorajado armazenar informações confidenciais no Armazenamento.Para ser honesto, vale a pena notar que hoje existem soluções mais avançadas para armazenar dados no lado do cliente - isto é IndexedDB, Service Workers + Cache API, etc.Você pode ler sobre os trabalhadores de serviço aqui .A API de armazenamento na Web inclui localStorage e sessionStorage. A diferença entre eles é o tempo de armazenamento de dados. No localStorage, os dados são armazenados permanentemente até serem excluídos "explicitamente" (nem recarregar a página nem fechá-la resulta na exclusão de dados). O tempo de armazenamento de dados no sessionStorage, como o nome indica, é limitado pela sessão do navegador. Como sessionStorage quase nunca é usado na prática, consideraremos apenas localStorage.O que você precisa saber sobre o localStorage?
- Ao usar localStorage, uma representação do objeto Storage é criada.
- Os dados no localStorage são armazenados como pares de chave / valor.
- Os dados são armazenados como seqüências de caracteres.
- Os dados não são classificados, o que às vezes leva à sua mistura (como veremos no exemplo da lista de tarefas).
- Quando você ativa o modo anônimo ou privado em seu navegador, o uso do armazenamento local pode se tornar impossível (depende do navegador).
localStorage possui os seguintes métodos:- Storage.key (n) - nome da chave com índice n
- Storage.getItem () - obtém o item
- Storage.setItem () - escreve um item
- Storage.removeItem () - exclui um item
- Storage.clear () - limpar armazenamento
- Storage.length - comprimento do armazenamento (número de elementos - pares chave / valor)
Na especificação, fica assim:interface Storage {
readonly attribute unsigned long length;
DOMString? key(unsigned long index);
getter DOMString? getItem(DOMString key);
setter void setItem(DOMString key, DOMString value);
deleter void removeItem(DOMString key);
void clear();
};
Os dados são gravados no armazenamento de uma das seguintes maneiras:localStorage.color = 'deepskyblue'
localStorage[color] = 'deepskyblue'
localStorage.setItem('color', 'deepskyblue')
Você pode obter os dados assim:localStorage.getItem('color')
localStorage['color']
Como iterar sobre chaves de armazenamento e obter valores?
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i)
console.log(`${key}: ${localStorage.getItem(key)}`)
}
let keys = Object.keys(localStorage)
for (let key of keys) {
console.log(`${key}: ${localStorage.getItem(key)}`)
}
Como observamos acima, os dados no armazenamento têm um formato de sequência, portanto, existem algumas dificuldades com a gravação de objetos, que podem ser facilmente resolvidas usando o tandem JSON.stringify () - JSON.parse ():localStorage.user = {
name: 'Harry'
}
console.dir(localStorage.user)
localStorage.user = JSON.stringify({
name: 'Harry'
})
let user = JSON.parse(localStorage.user)
console.dir(user.name)
Para interagir com o localStorage, existe um armazenamento especial de eventos (armazenamento), que ocorre quando os dados são gravados / excluídos. Possui as seguintes propriedades:- chave - chave
- oldValue - valor antigo
- newValue - novo valor
- url - endereço de armazenamento
- storageArea - o objeto no qual a alteração ocorreu
Na especificação, fica assim:[Constructor(DOMString type, optional StorageEventInit eventInitDict)]
interface StorageEvent : Event {
readonly attribute DOMString? key;
readonly attribute DOMString? oldValue;
readonly attribute DOMString? newValue;
readonly attribute DOMString url;
readonly attribute Storage? storageArea;
};
dictionary StorageEventInit : EventInit {
DOMString? key;
DOMString? oldValue;
DOMString? newValue;
DOMString url;
Storage? storageArea;
};
LocalStorage permite a criação de protótipos?
Storage.prototype.removeItems = function() {
for (item in arguments) {
this.removeItem(arguments[item])
}
}
localStorage.setItem('first', 'some value')
localStorage.setItem('second', 'some value')
localStorage.removeItems('first', 'second')
console.log(localStorage.length)
Como verificar dados no localStorage?
localStorage.setItem('name', 'Harry')
function isExist(name) {
return (!!localStorage[name])
}
isExist('name')
function isItemExist(name) {
return (name in localStorage)
}
isItemExist('name')
O navegador localStorage pode ser encontrado aqui:
Chega de palavras, é hora de começar a trabalhar.Exemplos de uso
Lembre-se do tempo de reprodução do vídeo
window.onload = () => {
let video = document.querySelector('video')
if(localStorage.currentTime) {
video.currentTime = localStorage.currentTime
}
video.addEventListener('timeupdate', () => localStorage.currentTime = video.currentTime)
}
O resultado é o seguinte:
Inicie o vídeo e pare a reprodução no terceiro segundo, por exemplo. O tempo que deixamos é armazenado em localStorage. Para verificar isso, recarregue ou feche / abra a página. Vemos que o tempo atual de reprodução de vídeo permanece o mesmo.CodepenGithubTrabalhamos com o formulário de login
A marcação é assim:<form>
Login: <input type="text">
Password: <input type="text">
<input type="submit">
</form>
Temos um formulário e três "entradas". Para a senha, usamos <input type = "text"> porque, se você usar o tipo correto (senha), o Chrome tentará salvar os dados inseridos, o que nos impedirá de implementar nossa própria funcionalidade.JavaScript:
let form = document.querySelector('form')
let login = document.querySelector('input')
let password = document.querySelector('input + input')
if (localStorage.length != 0) {
login.value = localStorage.login
password.value = localStorage.password
}
form.addEventListener('submit', () => {
localStorage.login = login.value
localStorage.password = password.value
if (login.value == 'hello' && password.value == 'world') {
document.write('welcome')
}
})
Observe que não "validamos" o formulário. Isso, em particular, permite gravar linhas vazias como nome de usuário e senha.O resultado é o seguinte:
Apresentamos palavras mágicas.
Os dados são gravados no localStorage e uma saudação é exibida na página.CodepenGithubEscrevendo a lógica da lista de tarefas
A marcação é assim:<input type="text"><button class="add">add task</button><button class="clear">clear storage</button>
<ul></ul>
Temos uma "entrada" para inserir uma tarefa, um botão para adicionar uma tarefa à lista, um botão para limpar a lista e o armazenamento e um contêiner para a lista.JavaScript:
let input = document.querySelector('input')
input.focus()
let addButton = document.querySelector('.add')
let list = document.querySelector('ul')
if (localStorage.length != 0) {
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i)
let template = `${localStorage.getItem(key)}`
list.insertAdjacentHTML('afterbegin', template)
}
document.querySelectorAll('.close').forEach(b => {
b.addEventListener('click', e => {
let item = e.target.parentElement
list.removeChild(item)
localStorage.removeItem(`${item.dataset.id}`)
})
})
}
window.addEventListener('keydown', e => {
if (e.keyCode == 13) addButton.click()
})
addButton.addEventListener('click', () => {
let text = input.value
let template = `<li data-id="${++localStorage.length}"><button class="close">V</button><time>${new Date().toLocaleDateString()}</time> <p>${text}</p></li>`
list.insertAdjacentHTML('afterbegin', template)
localStorage.setItem(`${++localStorage.length}`, template)
input.value = ''
document.querySelector('.close').addEventListener('click', e => {
let item = e.target.parentElement
list.removeChild(item)
localStorage.removeItem(`${item.dataset.id}`)
})
})
document.querySelector('.clear').onclick = () => {
localStorage.clear()
document.querySelectorAll('li').forEach(item => list.removeChild(item))
input.focus()
}
O resultado é o seguinte: As
tarefas adicionadas à lista são armazenadas no localStorage como marcação pronta. Quando a página é recarregada, a lista é formada a partir dos dados do armazenamento (há mixagem, que foi mencionada acima).
Remover uma tarefa da lista clicando na marca de seleção verde remove o par de chave / valor correspondente do repositório.CodepenGithubImplementação de bate-papo
A marcação é assim:<input type="text">
<button class="send">send message</button>
<button class="save">save chat</button>
<button class="clear">clear chat</button>
<div></div>
Temos uma entrada para inserir uma mensagem, três botões: para enviar uma mensagem, salvar correspondência e limpar bate-papo e armazenamento, além de um contêiner para mensagens.JavaScript:
let input = document.querySelector('input')
input.focus()
let sendButton = document.querySelector('.send')
let saveButton = document.querySelector('.save')
let clearButton = document.querySelector('.clear')
let box = document.querySelector('div')
if (localStorage.messages) {
localStorage.messages
.split('</p>,')
.map(p => box.insertAdjacentHTML('beforeend', p))
}
sendButton.addEventListener('click', () => {
let text = document.querySelector('input').value
let template = `<p><time>${new Date().toLocaleTimeString()}</time> ${text}</p>`
box.insertAdjacentHTML('afterbegin', template)
input.value = ''
localStorage.message = template
})
window.addEventListener('keydown', e => {
if (e.keyCode == 13) sendButton.click()
})
window.addEventListener('storage', event => {
if (event.key == 'messages') return
event.newValue == null ? clearButton.click() : box.insertAdjacentHTML('afterbegin', event.newValue)
})
saveButton.addEventListener('click', () => {
let messages = []
document.querySelectorAll('p').forEach(p => messages.push(p.outerHTML))
localStorage.messages = messages
})
clearButton.addEventListener('click', () => {
localStorage.clear()
document.querySelectorAll('p').forEach(p => box.removeChild(p))
input.focus()
})
O resultado é o seguinte: A
mensagem que está sendo enviada é gravada em localStorage.message. O evento "storage" permite que você organize a troca de mensagens entre as guias do navegador.
Quando um bate-papo é salvo, todas as mensagens são gravadas em localStorage.messages. Quando a página é recarregada, a correspondência é formada a partir das mensagens gravadas.CodepenGithubLayout do carrinho de compras
Não pretendemos criar uma cesta totalmente funcional; portanto, o código será escrito "no estilo antigo".O layout de um produto fica assim:<div class="item">
<h3 class="title">Item1</h3>
<img src="http://placeimg.com/150/200/tech" alt="#">
<p>Price: <span class="price">1000</span></p>
<button class="add" data-id="1">Buy</button>
</div>
Temos um contêiner para as mercadorias, o nome, a imagem e o preço das mercadorias, além de um botão para adicionar mercadorias à cesta.Também temos um contêiner para botões para exibir o conteúdo da cesta e esvaziar a cesta e o armazenamento e um contêiner para a cesta.<div class="buttons">
<button id="open">Cart</button>
<button id="clear">Clear</button>
</div>
<div id="content"></div>
JavaScript:
let itemBox = document.querySelectorAll('.item'),
cart = document.getElementById('content');
function getCartData() {
return JSON.parse(localStorage.getItem('cart'));
}
function setCartData(o) {
localStorage.setItem('cart', JSON.stringify(o));
}
function addToCart() {
this.disabled = true;
let cartData = getCartData() || {},
parentBox = this.parentNode,
itemId = this.getAttribute('data-id'),
itemTitle = parentBox.querySelector('.title').innerHTML,
itemPrice = parentBox.querySelector('.price').innerHTML;
if (cartData.hasOwnProperty(itemId)) {
cartData[itemId][2] += 1;
} else {
cartData[itemId] = [itemTitle, itemPrice, 1];
}
if (!setCartData(cartData)) {
this.disabled = false;
}
}
for (let i = 0; i < itemBox.length; i++) {
itemBox[i].querySelector('.add').addEventListener('click', addToCart)
}
function openCart() {
let cartData = getCartData(),
totalItems = '',
totalGoods = 0,
totalPrice = 0;
if (cartData !== null) {
totalItems = '<table><tr><th>Name</th><th>Price</th><th>Amount</th></tr>';
for (let items in cartData) {
totalItems += '<tr>';
for (let i = 0; i < cartData[items].length; i++) {
totalItems += '<td>' + cartData[items][i] + '</td>';
}
totalItems += '</tr>';
totalGoods += cartData[items][2];
totalPrice += cartData[items][1] * cartData[items][2];
}
totalItems += '</table>';
cart.innerHTML = totalItems;
cart.append(document.createElement('p').innerHTML = 'Goods: ' + totalGoods + '. Price: ' + totalPrice);
} else {
cart.innerHTML = 'empty';
}
}
document.getElementById('open').addEventListener('click', openCart);
document.getElementById('clear').addEventListener('click', () => {
localStorage.removeItem('cart');
cart.innerHTML = 'leared';
});
O resultado é o seguinte:
Os produtos selecionados são registrados na loja como um único par de chave / valor.
Quando você clica no botão Carrinho, os dados do localStorage são exibidos em uma tabela, o número total de mercadorias e seu valor são calculados.CodepenGithubObrigado por sua atenção.