Как работать с localStorage в JavaScript
В этой статье вы узнаете о том, что такое localStorage
и на рабочем примере узнаем то, как с ним работать в JavaScript.
Мне нравится делать обучающие материалы о том, как создавать небольшие приложения буквально с нуля, используя чистый JavaScript. Создание to-do списка это распространенная идея для создания приложения, а без базы данных, в которую можно положить задачи, она становится особенной полезной, но добавляет некоторые сложности для начинающих.
Однако, даже без базы данных, мы можем использовать встроенное в браузер веб-хранилище, чтобы сохранять туда задачи из to-do списка.Такое приложение было бы особенно полезным для создания быстрых заметок. Вы бы просто установили ярлык на приложение при запуске новой вкладки и задачи to-do будут находиться на вашем компьютере пока вы не очистите кэш.
Вот то, что мы сегодня будем делать:
Для того, чтобы понимать статью, вам нужно знать основы HTML и CSS, понимать типы данных и синтаксис JavaScript, вместе с DOM манипуляциями.
Целью этой статьи является создание быстрого приложения, которое будет хранить to-do элементы в веб-хранилище браузера на вашем компьютере и показывать их на фронте. Посмотрите пример.
Что такое веб-хранилище
В веб-хранилище хранятся данные пользователя браузера. Есть два типа веб-хранилищ:
localStorage
— это данные, которые хранятся бессрочно и будут доступны даже после перезагрузки браузера.
sessionStorage
— это данные, которые стираются после того, как окно браузера закрывается.
Веб-хранилище довольно удобно для сохранения данных, таких как предпочтения пользователей (светлая или темная цветовая схема на сайте и тп), сохранение товаров, положенных в корзину или запоминание того, что пользователь залогинен на сайте.
До этого, для запоминания такого рода локальных, временных данных, использовались только кукисы. В локальном веб-хранилище вы можете хранить значительно больше данных (5MB vs 4KB) и не обращаться к ним, при каждом HTTP вызове, таким образом, это может быть лучшим вариантом для хранилища данных на стороне клиента.
Вот обзор методов localStorage
setItem()
— добавляет пару ключ-значение в локальное веб-хранилище
getItem()
— получает значение по ключу
removeItem()
— удаляет элемент по ключу
clear()
— очищает хранилище
Вы можете посмотреть то, что находится в локальном хранилище, зайдя в консоль и введя в неё localStorage
.
Storage {length: 0}
Добавление данных в localStorage
очень простой процесс, вы можете использовать setItem()
метод. Я буду использовать общепринятые имена для пары ключ-значение, но они могут быть любой производной строкой.
localStorage.setItem('key', 'value')
Теперь, если вы проверите localStorage
в консоле, то вы там увидите новый ключ и значение.
Storage {key: "value", length: 1}
Если вы хотите получить значение конкретного ключа, то вам надо будет использовать метод getItem()
.
localStorage.getItem('key')
value
И наконец, вы можете удалить данные с помощью removeItem()
.
localStorage.removeItem('key')
А используя clear()
, вы очистите всё веб-хранилище.
localStorage.clear()
Теперь мы можем приступить к созданию приложения.
Подготавливаем фронт
Сначала мы создадим простенькую HTML разметку в index.html
. Я работаю в Primitive(мой минималистический HTML Фреймворк) для стилей, потому что это то, что я всегда использую, если мне нужен быстрый фронт.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Tab App</title>
<link rel="stylesheet" href="https://unpkg.com/primitive-ui/dist/css/main.css" />
</head>
<body>
<div class="small-container">
<h1>New Tab App</h1>
<!-- more will go here -->
</div>
<script src="js/scripts.js"></script>
</body>
</html>
Тут нам надо уделить внимание настройке трёх вещей:
Текстовой input
— для добавления новых элементов.
Список — то место, куда будут добавляться новые элементы на фронте.
Кнопка — для сброса всех элементов.
Добавьте этот код туда, где стоит комментарий <! — more will go here — >
<form>
<input id="item" type="text" placeholder="New" required />
</form>
<h2>Items</h2>
<ul></ul>
<button>Clear All</button>
И вот, как всё это будет выглядеть.
Далее мы сосредоточимся на написании функционала в JavaScript.
Пишем функционал на JavaScript
Перед тем, как интегрировать всё это с локальным веб-хранилищем, давайте подцепим на JS форму и список, через которые мы хотим добавлять данные в input и выводить их в ul
.
Для начала, я собираюсь объявить несколько переменных для элементов на странице.
const form = document.querySelector('form')
const ul = document.querySelector('ul')
const button = document.querySelector('button')
const input = document.getElementById('item')
Далее, я напишу функцию, которая создаст элемент li
, так как этот функционал нам потребуется очень часто. Я назову функцию liMaker()
. Она просто будет создавать элемент li
, выставлять ему текст, который будет как параметр и добавлять созданный li
в ul
.
const liMaker = text => {
const li = document.createElement('li')
li.textContent = text
ul.appendChild(li)
}
Далее, я собираюсь добавить прослушиватель события на форму, которая связана с submit
— событие, которое будет происходить всякий раз, как мы нажмем на enter в форме.e.preventDefault()
предотвратит отправку формы при сабмите, это нам не нужно, так как мы не собираемся отправлять никаких данных на сервер.
Вместо этого, форма отправит значение input
. Мы вызовем функцию liMaker()
, которая создаст элемент с текстом, который будет значением input
и далее, мы добавим это в DOM. И под конец, мы выставим значение input
на пустую строку, таким образом вам не придётся вручную стирать то, что вы только написали.
form.addEventListener('submit', function(e) {
e.preventDefault()
liMaker(input.value)
input.value = ''
})
Теперь, с буквально пустяковым количеством кода на борту, мы имеем небольшое приложение, которое добавляет to-do элементы в список задач.
Но, так как мы нигде не сохраняем наши данные, то при закрытии или обновлении браузера, введенные нами элементы исчезнут. Последним шагом будет интеграция нашего приложения с локальным хранилищем, для того, чтобы данные оставались в нём и после перезагрузки страницы, и после перезагрузки браузера.
Интегрируем локальное хранилище
Сейчас мы добавим немного функционала в наше приложение. Во первых, каждый раз, когда форму будут сабмитить, значение из input
будет добавлено в localStorage
вместе с мгновенным отображением в списке задач. Также, нам нужно будет пробежаться циклом по всему локальному хранилищу и показать элементы этого хранилища сверху списка существующих задач. Ну и под конец, мы добавим кнопку “Clear All”, которая удалит все элементы не только из локального хранилища, но и из списка ul
.
Давайте сначала создадим пустой массив и создадим в localStorage
ключ под названием items
. localStorage
в виде значений ключей принимает только строки, к тому же, нам надо хранить задачи в массиве.
Мы можем обойти это ограничение с помощью JSON.stringify()
, чтобы конвертировать массив в строку. А уже потом мы применим JSON.parse()
для конвертирования содержимого localStorage
в какой-нибудь рабочий формат, который мы положим в переменную data
. Вставьте этот код под всем, что мы написали выше.
let itemsArray = []
localStorage.setItem('items', JSON.stringify(itemsArray))
const data = JSON.parse(localStorage.getItem('items'))
В слушателе событий мы будем отправлять каждое новое значение input
в массив, а затем добавлять в localStorage
новое значение с уже обновленным массивом.
e.preventDefault()
itemsArray.push(input.value)
localStorage.setItem('items', JSON.stringify(itemsArray))
Далее, мы собираемся пробежаться по всему содержимому переменной data
, которая содержит всё из нашего localStorage
в таком виде, в котором мы можем работать с этими данным в JavaScript. Затем мы заново запустим liMaker()
. Это покажет нам всю нужную информацию в списке при каждом открытии приложения.
data.forEach(item => {
liMaker(item)
})
И под конец мы добавим событие по клику на кнопку, которая очистит все данные из localStorage
и удалит все потомков у ul
.
button.addEventListener('click', function() {
localStorage.clear()
while (ul.firstChild) {
ul.removeChild(ul.firstChild)
}
})
Если всё пройдет хорошо, то данные запишутся в хранилище и покажутся в списке задач, а само хранилище вы сможете проверить введя localStorage
в консоли.
Storage {items:
"["Welcome","to","the","Thunderdome"]",
length: 1}
Но у нас осталась последняя проблема. После закрытия браузера или перезагрузки страницы, вся существующая информация в localStorage
пропадает и ничего не остается на нашем фронте. Почему?
Потому, что наш itemsArray
сбрасывается каждый раз при запуске скрипта. Мы можем пофиксить эту проблемку, создав условие, которое проверит наличие доступного localStorage
:
let items
if (localStorage.getItem('items')) {
items = JSON.parse(localStorage.getItem('items'))
} else {
items = []
}
Практичнее было бы использовать тернарный оператор.
let itemsArray = localStorage.getItem('items') ? JSON.parse(localStorage.getItem('items')) : []
Теперь наше приложение завершено. И когда вы вводите какую-либо информацию, а затем обновляете или закрываете окно браузера, данные будут на месте, пока вы самостоятельно не очистите их в настройках браузера или запустив команду localStorage.clear()
. Ну а вот и полный код JavaScript.
const form = document.querySelector('form')
const ul = document.querySelector('ul')
const button = document.querySelector('button')
const input = document.getElementById('item')
let itemsArray = localStorage.getItem('items') ? JSON.parse(localStorage.getItem('items')) : []
localStorage.setItem('items', JSON.stringify(itemsArray))
const data = JSON.parse(localStorage.getItem('items'))
const liMaker = text => {
const li = document.createElement('li')
li.textContent = text
ul.appendChild(li)
}
form.addEventListener('submit', function(e) {
e.preventDefault()
itemsArray.push(input.value)
localStorage.setItem('items', JSON.stringify(itemsArray))
liMaker(input.value)
input.value = ''
})
data.forEach(item => {
liMaker(item)
})
button.addEventListener('click', function() {
localStorage.clear()
while (ul.firstChild) {
ul.removeChild(ul.firstChild)
}
})
Заключение
В этом руководстве мы узнали о том, как сделать простое to-do приложение, которое можно использовать для быстрого напоминания о текущих задачах, просто вызвав новую вкладку, используя HTML5 веб-хранилище. Я надеюсь, что теперь у вас появилось лучшее понимание локального хранилища и того, как интегрировать его в простое приложение.
Почитайте про применение localStorage в следующей статье — Используем localStorage в React