Studi Kasus API Penyimpanan Web



Selamat siang teman!

Dalam artikel ini, kita akan melihat beberapa contoh menggunakan API Penyimpanan Web atau objek Penyimpanan.

Apa yang akan kita lakukan?

  • Belajarlah untuk mengingat waktu pemutaran video.
  • Kami akan bekerja dengan formulir login halaman.
  • Mari kita menulis logika dari daftar tugas.
  • Kami menerapkan obrolan.
  • Buat sketsa keranjang barang.

Jadi ayo pergi.

Ulasan singkat


Objek Penyimpanan digunakan untuk menyimpan data di sisi klien dan, dalam hal ini, bertindak sebagai alternatif untuk cookie. Keuntungan dari Storage adalah ukuran penyimpanan (dari 5 MB, itu tergantung pada browser, ketika batas terlampaui, kesalahan "QUOTA_EXCEEDED_ERR" dilemparkan) dan tidak perlu mengakses server. Kelemahan yang signifikan adalah keamanan: dibutuhkan skrip berbahaya untuk mengakses halaman, dan penulisan hilang. Oleh karena itu, sangat disarankan untuk menyimpan informasi rahasia di Storage.

Dalam keadilan, perlu dicatat bahwa hari ini ada solusi yang lebih maju untuk menyimpan data di sisi klien - ini adalah IndexedDB, Pekerja Layanan + API Cache, dll.

Anda dapat membaca tentang pekerja layanan di sini .

API Penyimpanan Web termasuk penyimpanan lokal dan sessionStorage. Perbedaan di antara mereka adalah waktu penyimpanan data. Di localStorage, data disimpan secara permanen hingga "secara eksplisit" dihapus (tidak memuat ulang halaman atau menutupnya menghasilkan penghapusan data). Waktu penyimpanan data di sessionStorage, sesuai namanya, dibatasi oleh sesi browser. Karena sessionStorage hampir tidak pernah digunakan dalam praktik, kami hanya akan mempertimbangkan localStorage.

Apa yang perlu Anda ketahui tentang penyimpanan lokal?


  • Saat menggunakan localStorage, representasi dari objek Storage dibuat.
  • Data dalam penyimpanan lokal disimpan sebagai pasangan kunci / nilai.
  • Data disimpan sebagai string.
  • Data tidak diurutkan, yang kadang-kadang mengarah ke pencampuran mereka (seperti yang akan kita lihat dengan contoh daftar tugas).
  • Saat Anda mengaktifkan mode penyamaran atau pribadi di browser Anda, menggunakan localStorage mungkin menjadi tidak mungkin (tergantung browser).

localStorage memiliki metode berikut:

  • Storage.key (n) - nama kunci dengan indeks n
  • Storage.getItem () - dapatkan item
  • Storage.setItem () - menulis item
  • Storage.removeItem () - menghapus item
  • Storage.clear () - membersihkan penyimpanan
  • Storage.length - panjang penyimpanan (jumlah elemen - pasangan kunci / nilai)

Dalam spesifikasinya, tampilannya seperti ini:

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

Data ditulis ke penyimpanan dengan salah satu cara berikut:

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

Anda bisa mendapatkan data seperti ini:

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

Bagaimana cara mengulangi kunci penyimpanan dan mendapatkan nilai?


//  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)}`)
}

Seperti yang kita catat di atas, data dalam penyimpanan memiliki format string, jadi ada beberapa kesulitan dengan menulis objek, yang dapat dengan mudah dipecahkan menggunakan JSON.stringify () - JSON.parse () tandem:

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

Untuk berinteraksi dengan penyimpanan lokal, ada acara khusus - penyimpanan (penyimpanan), yang terjadi ketika data ditulis / dihapus. Ini memiliki sifat-sifat berikut:

  • kunci - kunci
  • oldValue - nilai lama
  • newValue - nilai baru
  • url - alamat penyimpanan
  • storageArea - objek di mana perubahan terjadi

Dalam spesifikasinya, tampilannya seperti ini:

[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;
};

Apakah localStorage memungkinkan pembuatan prototipe?


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

Bagaimana cara memeriksa data di 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

Browser localStorage dapat ditemukan di sini:



Cukup kata-kata, saatnya untuk turun ke bisnis.

Contoh penggunaan


Ingat waktu pemutaran video


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

Hasilnya terlihat seperti ini:



Mulai video dan hentikan pemutaran pada detik ketiga, misalnya. Waktu yang kami tinggalkan disimpan di Penyimpanan lokal. Untuk memverifikasi ini, muat ulang atau tutup / buka halaman. Kami melihat bahwa waktu pemutaran video saat ini tetap sama.

Codepen

Github

Kami bekerja dengan formulir login


Markupnya terlihat seperti ini:

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

Kami memiliki formulir dan tiga "input." Untuk kata sandi, kami menggunakan <input type = "text">, karena jika Anda menggunakan jenis yang benar (kata sandi), Chrome akan mencoba untuk menyimpan data yang dimasukkan, yang akan mencegah kami dari mengimplementasikan fungsionalitas kami sendiri.

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

Harap dicatat bahwa kami tidak "memvalidasi" formulir. Ini, khususnya, memungkinkan Anda untuk merekam baris kosong sebagai nama pengguna dan kata sandi.

Hasilnya terlihat seperti ini:



Kami memperkenalkan kata-kata ajaib.



Data ditulis ke localStorage, dan salam ditampilkan di halaman.

Codepen

Github

Menulis logika dari daftar tugas


Markupnya terlihat seperti ini:

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

<ul></ul>

Kami memiliki "input" untuk memasukkan tugas, tombol untuk menambahkan tugas ke daftar, tombol untuk membersihkan daftar dan penyimpanan, dan wadah untuk daftar.

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

Hasilnya terlihat seperti ini:



Tugas yang ditambahkan ke daftar disimpan di localStorage sebagai markup yang sudah jadi. Ketika halaman dimuat ulang, daftar terbentuk dari data penyimpanan (ada pencampuran, yang disebutkan di atas).



Menghapus tugas dari daftar dengan mengklik tanda centang hijau menghapus pasangan kunci / nilai yang sesuai dari repositori.

Codepen

Github

Implementasi Obrolan


Markupnya terlihat seperti ini:

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

<div></div>

Kami memiliki input untuk memasukkan pesan, tiga tombol: untuk mengirim pesan, untuk menyimpan korespondensi dan untuk membersihkan obrolan dan penyimpanan, serta wadah untuk pesan.

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

Hasilnya terlihat seperti ini:



Pesan yang dikirim ditulis ke localStorage.message. Acara "penyimpanan" memungkinkan Anda untuk mengatur pertukaran pesan di antara tab browser.



Ketika obrolan disimpan, semua pesan ditulis ke localStorage.messages. Ketika halaman dimuat ulang, korespondensi terbentuk dari pesan yang direkam.

Codepen

Github

Tata letak keranjang belanja


Kami tidak bertujuan untuk membuat keranjang yang berfungsi penuh, sehingga kode akan ditulis "dalam gaya lama."

Tata letak satu produk terlihat seperti ini:

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

Kami memiliki wadah untuk barang, nama, gambar, dan harga barang, serta tombol untuk menambahkan barang ke keranjang.

Kami juga memiliki wadah untuk kancing untuk menampilkan isi keranjang dan mengosongkan keranjang dan penyimpanan dan wadah untuk keranjang.

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

Hasilnya terlihat seperti ini:



Produk yang dipilih dicatat di toko sebagai pasangan kunci / nilai tunggal.



Ketika Anda mengklik tombol Cart, data dari localStorage ditampilkan dalam sebuah tabel, jumlah total barang dan nilainya dihitung.

Codepen

Github

Terima kasih atas perhatian Anda.

All Articles