Études de cas sur l'API de stockage Web



Bonjour mes amis!

Dans cet article, nous allons voir quelques exemples d'utilisation de l'API Web Storage ou de l'objet Storage.

Qu'allons-nous faire exactement?

  • Apprenez à vous souvenir du temps de lecture vidéo.
  • Nous travaillerons avec le formulaire de connexion à la page.
  • Écrivons la logique de la liste des tâches.
  • Nous implémentons le chat.
  • Esquissez un panier de marchandises.

Alors allons-y.

Bref avis


L'objet de stockage est utilisé pour stocker des données côté client et, en ce sens, agit comme une alternative aux cookies. L'avantage du stockage est la taille du stockage (à partir de 5 Mo, cela dépend du navigateur, lorsque la limite est dépassée, l'erreur «QUOTA_EXCEEDED_ERR» est levée) et il n'est pas nécessaire d'accéder au serveur. Un inconvénient important est la sécurité: l'accès à la page coûte un script malveillant et l'écriture est perdue. Par conséquent, il est fortement déconseillé de stocker des informations confidentielles dans le stockage.

En toute honnêteté, il convient de noter qu'aujourd'hui, il existe des solutions plus avancées pour le stockage de données côté client - il s'agit d'IndexDD, Service Workers + Cache API, etc.

Vous pouvez en savoir plus sur les travailleurs de service ici .

L'API de stockage Web inclut localStorage et sessionStorage. La différence entre eux est la durée de stockage des données. Dans localStorage, les données sont stockées de manière permanente jusqu'à ce qu'elles soient supprimées "explicitement" (ni recharger la page ni la fermer entraîne la suppression des données). Le temps de stockage des données dans sessionStorage, comme son nom l'indique, est limité par la session du navigateur. Puisque sessionStorage n'est presque jamais utilisé en pratique, nous ne considérerons que localStorage.

Ce que vous devez savoir sur localStorage?


  • Lorsque vous utilisez localStorage, une représentation de l'objet Storage est créée.
  • Les données dans localStorage sont stockées sous forme de paires clé / valeur.
  • Les données sont stockées sous forme de chaînes.
  • Les données ne sont pas triées, ce qui conduit parfois à leur mixage (comme nous le verrons avec l'exemple de la liste des tâches).
  • Lorsque vous activez le mode navigation privée ou privée dans votre navigateur, l'utilisation de localStorage peut devenir impossible (en fonction du navigateur).

localStorage a les méthodes suivantes:

  • Storage.key (n) - nom de la clé avec l'index n
  • Storage.getItem () - récupère l'élément
  • Storage.setItem () - écrire un élément
  • Storage.removeItem () - supprimer un élément
  • Storage.clear () - effacer le stockage
  • Storage.length - longueur de stockage (nombre d'éléments - paires clé / valeur)

Dans la spécification, cela ressemble à ceci:

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();
};

Les données sont écrites sur le stockage de l'une des manières suivantes:

localStorage.color = 'deepskyblue'
localStorage[color] = 'deepskyblue'
localStorage.setItem('color', 'deepskyblue') //    

Vous pouvez obtenir les données comme ceci:

localStorage.getItem('color')
localStorage['color']

Comment parcourir les clés de stockage et obtenir des valeurs?


//  1
for (let i = 0; i < localStorage.length; i++) {
    let key = localStorage.key(i)
    console.log(`${key}: ${localStorage.getItem(key)}`)
}

//  2
let keys = Object.keys(localStorage)
for (let key of keys) {
    console.log(`${key}: ${localStorage.getItem(key)}`)
}

Comme nous l'avons noté ci-dessus, les données dans le stockage ont un format de chaîne, il y a donc quelques difficultés avec l'écriture d'objets, qui peuvent être facilement résolues en utilisant le tandem JSON.stringify () - JSON.parse ():

localStorage.user = {
    name: 'Harry'
}
console.dir(localStorage.user) // [object Object]

localStorage.user = JSON.stringify({
    name: 'Harry'
})
let user = JSON.parse(localStorage.user)
console.dir(user.name) // Harry

Pour interagir avec localStorage, il existe un événement spécial - le stockage (onstorage), qui se produit lorsque les données sont écrites / supprimées. Il a les propriétés suivantes:

  • clé - clé
  • oldValue - ancienne valeur
  • newValue - nouvelle valeur
  • url - adresse de stockage
  • storageArea - l'objet dans lequel la modification s'est produite

Dans la spécification, cela ressemble à ceci:

[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 permet-il le prototypage?


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) // 0

Comment vérifier les données dans localStorage?


//  1
localStorage.setItem('name', 'Harry')

function isExist(name) {
    return (!!localStorage[name])
}

isExist('name') // true

//  2
function isItemExist(name) {
    return (name in localStorage)
}

isItemExist('name') // true

Le navigateur localStorage se trouve ici:



Assez de mots, il est temps de passer aux choses sérieuses.

Exemples d'utilisation


Rappelez-vous le temps de lecture vidéo


window.onload = () => {
    //   <video>
    let video = document.querySelector('video')
    
    //  localStorage   currentTime ( ),    video.currentTime
    if(localStorage.currentTime) {
        video.currentTime = localStorage.currentTime
    }
    
    //    video.currentTime,     localStorage.currentTime
    video.addEventListener('timeupdate', () => localStorage.currentTime = video.currentTime)
}

Le résultat ressemble à ceci:



Démarrez la vidéo et arrêtez la lecture à la troisième seconde, par exemple. Le temps que nous avons laissé est stocké dans localStorage. Pour vérifier cela, rechargez ou fermez / ouvrez la page. Nous voyons que le temps de lecture vidéo actuel reste le même.

Codepen

Github

Nous travaillons avec le formulaire de connexion


Le balisage ressemble à ceci:

<form>
    Login: <input type="text">
    Password: <input type="text">
    <input type="submit">
</form>

Nous avons un formulaire et trois «entrées». Pour le mot de passe, nous utilisons <input type = "text">, car si vous utilisez le bon type (mot de passe), Chrome essaiera d'enregistrer les données saisies, ce qui nous empêchera de mettre en œuvre nos propres fonctionnalités.

JavaScript:

//         
let form = document.querySelector('form')
let login = document.querySelector('input')
let password = document.querySelector('input + input')

//  localStorage  
//     
//    
if (localStorage.length != 0) {
    login.value = localStorage.login
    password.value = localStorage.password
}

//      "submit"
form.addEventListener('submit', () => {
    //      localStorage
    localStorage.login = login.value
    localStorage.password = password.value
    
    //    hello  world     , 
    //       "welcome"  
    if (login.value == 'hello' && password.value == 'world') {
        document.write('welcome')
    }
})

Veuillez noter que nous ne "validons" pas le formulaire. Cela vous permet notamment d'enregistrer des lignes vides en tant que nom d'utilisateur et mot de passe.

Le résultat ressemble à ceci:



nous introduisons des mots magiques.



Les données sont écrites dans localStorage et un message d'accueil s'affiche sur la page.

Codepen

Github

Rédaction de la logique de la liste des tâches


Le balisage ressemble à ceci:

<input type="text"><button class="add">add task</button><button class="clear">clear storage</button>

<ul></ul>

Nous avons une «entrée» pour entrer une tâche, un bouton pour ajouter une tâche à la liste, un bouton pour nettoyer la liste et le stockage, et un conteneur pour la liste.

JavaScript:

//      
let input = document.querySelector('input')
input.focus()
//       
let addButton = document.querySelector('.add')
//    
let list = document.querySelector('ul')

//   localStorage  
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)
    }
    
    //      "close" -    
    document.querySelectorAll('.close').forEach(b => {
        //   
        b.addEventListener('click', e => {
            //    "li"
            let item = e.target.parentElement
            //    
            list.removeChild(item)
            //    localStorage
            localStorage.removeItem(`${item.dataset.id}`)
        })
    })
}

//       "Enter"
window.addEventListener('keydown', e => {
    if (e.keyCode == 13) addButton.click()
})

//           ""
addButton.addEventListener('click', () => {
    //   - 
    let text = input.value
    //  ,          "data-id"
    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
    localStorage.setItem(`${++localStorage.length}`, template)
    //   
    input.value = ''

    //           ""
    document.querySelector('.close').addEventListener('click', e => {
        //    -   
        let item = e.target.parentElement
        //    
        list.removeChild(item)
        //    localStorage
        localStorage.removeItem(`${item.dataset.id}`)
    })
})

//        ""
document.querySelector('.clear').onclick = () => {
    //  
    localStorage.clear()
    //    
    document.querySelectorAll('li').forEach(item => list.removeChild(item))
    //   
    input.focus()
}

Le résultat ressemble à ceci: les



tâches ajoutées à la liste sont stockées dans localStorage en tant que balisage prêt à l'emploi. Lorsque la page est rechargée, la liste est formée à partir des données du stockage (il y a mixage, qui a été mentionné ci-dessus).



La suppression d'une tâche de la liste en cliquant sur la coche verte supprime la paire clé / valeur correspondante du référentiel.

Codepen

Github

Implémentation du chat


Le balisage ressemble à ceci:

<input type="text">
<button class="send">send message</button>
<button class="save">save chat</button>
<button class="clear">clear chat</button>

<div></div>

Nous avons une entrée pour entrer un message, trois boutons: pour envoyer un message, pour sauvegarder la correspondance et pour nettoyer le chat et le stockage, ainsi qu'un conteneur pour les messages.

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')

//      "messages"
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
})

//       "Enter"
window.addEventListener('keydown', e => {
    if (e.keyCode == 13) sendButton.click()
})

//   "storage"
window.addEventListener('storage', event => {
    //     "messages"
    //  
    if (event.key == 'messages') return
    //      null
    //     
    //     
    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()
})

Le résultat ressemble à ceci: Le



message envoyé est écrit dans localStorage.message. L'événement "stockage" vous permet d'organiser l'échange de messages entre les onglets du navigateur.



Lorsqu'un chat est enregistré, tous les messages sont écrits dans localStorage.messages. Lorsque la page est rechargée, une correspondance est formée à partir des messages enregistrés.

Codepen

Github

Disposition du panier


Nous ne visons pas à créer un panier entièrement fonctionnel, le code sera donc écrit "à l'ancienne".

La présentation d'un produit ressemble à ceci:

<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>

Nous avons un conteneur pour les marchandises, le nom, l'image et le prix des marchandises, ainsi qu'un bouton pour ajouter des marchandises au panier.

Nous avons également un conteneur pour les boutons pour afficher le contenu du panier et vider le panier et le stockage et un conteneur pour le panier.

<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');

//    localStorage
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() || {},
        //    "Buy"
        parentBox = this.parentNode,
        // id 
        itemId = this.getAttribute('data-id'),
        //  
        itemTitle = parentBox.querySelector('.title').innerHTML,
        //  
        itemPrice = parentBox.querySelector('.price').innerHTML;
    // +1  
    if (cartData.hasOwnProperty(itemId)) {
        cartData[itemId][2] += 1;
    } else {
        // + 
        cartData[itemId] = [itemTitle, itemPrice, 1];
    }
    //    localStorage
    if (!setCartData(cartData)) {
        //   
        this.disabled = false;
    }
}

//    ""    "Buy"
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';
});

Le résultat ressemble à ceci:



Les produits sélectionnés sont enregistrés dans le magasin comme une seule paire clé / valeur.



Lorsque vous cliquez sur le bouton Panier, les données de localStorage sont affichées dans un tableau, le nombre total de marchandises et leur valeur sont calculés.

Codepen

Github

Merci de votre attention.

All Articles