Сохранение изображений на стороне клиента с использованием LocalStorage
LocalStorage API предоставляет разработчикам прямой доступ к хранилищу данных, которое можно использовать для хранения информации на стороне клиента. Это позволит ускорить рендеринг веб-приложений за счет уменьшения количества запросов к базе данных.
Для демонстрации данного подхода мы создадим проект, в котором пользователь может загружать изображения на свой ПК, хранить их и удалять.
Шаг 1
Сначала создадим простой HTML-файл.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Upload Image</title>
</head>
<body>
</body>
</html>
Для загрузки изображений будем использовать input type="file". Мы применим к нему несколько стилевых свойств.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Upload Image</title>
</head>
<body>
<div class="row">
<div class="input_box">
<label for="">
<input type="file" id="myFile" size="50" onchange="uploadImage(event)">
</label>
</div>
</div>
</body>
</html>
Данный элемент ввода я подписал на событие onchange, которое будет обрабатываться функцией uploadImage(event).
Стилизуем input type="file":
<style>
.row{
display: flex;
}
.input_box {
position: relative;
height: 75px;
width: 50%;
margin: 0 auto;
background-color: cadetblue;
cursor: pointer;
overflow: hidden;
text-align: center;
-webkit-transition: background-color ease-in-out 150ms;
transition: background-color ease-in-out 150ms;
}
.input_box input {
width: 100%;
height: 100%;
opacity: 0;
overflow: hidden;
position: absolute;
}
.input_box label {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
height: 100%;
font-weight: 400;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
overflow: hidden;
}
.input_box label::after {
content: '+';
font-family: 'Material Icons';
position: absolute;
font-size: 2.5rem;
color: #e6e6e6;
top: calc(50% - 2.5rem);
left: calc(50% - 1.25rem);
z-index: 0;
line-height: 2;
}
.input_box label:hover{
background-color: transparent;
color: cadetblue;
}
</style>
Шаг 2
Создадим функцию для загрузки изображений в localStorage на стороне клиента.
<script>
function uploadImage(event)
{
}
</script>
Шаг 3
Затем с помощью объекта FileReader мы сможем получить содержимое файла изображения в формате base64. После чего оно будет сохранено в localStorage с именем файла в качестве ключа.
Теперь LocalStorage имеет атрибуты ключа и значения. Ключом является имя файла, а содержимое изображения – значением.
<script>
function uploadImage(event) {
var reader = new FileReader();
var name = event.target.files[0].name;
reader.addEventListener("load", function () {
if (this.result && localStorage) {
window.localStorage.setItem(name, this.result);
} else {
alert();
}
});
reader.readAsDataURL(event.target.files[0]);
}
</script>
В приведенном выше примере сначала создается новый экземпляр объекта FileReader, после чего сохраняется имя файла в переменной name.
С помощью функции reader.readAsDataURL мы получаем содержимое файла. Функция reader.addEventListener сохраняет изображение локально.
В приведенной выше функции (в конструкции If) используется два условия. this.result проверяет, поддерживает ли браузер локальное хранилище или нет.
Чтобы поместить содержимое в хранилище, используется функция localstorage.setItem(). В нее мы передаем ключ и значение для его сохранения.
Шаг 4
Для реализации предварительного просмотра изображения добавим кнопку, при нажатии на которую сработает функция showImage().
<div class="row">
<div class="input_box">
<label for="">
<input type="file" id="myFile" size="50" onchange="uploadImage(event)">
</label>
</div>
<button onclick="showImages()" style="justify-content: center;" class="btn btn-primary">
Show Images
</button>
</div>
Шаг 5
Добавим стилей:
.btn {
padding: 16px 25px;
border: 0;
background-color: #444;
color: white;
border-radius: 50px;
cursor: pointer;
transition: .25s all;
height: 50px;
width: 30%;
margin: 10px auto;
}
.btn:hover {
transform: translateY(-2%);
color: #444;
background: transparent;
border: 1px solid #444;
}
.btn:focus {
outline: none;
}
Чтобы функция showImage() работала, необходимо получить изображения из хранилища. Для этого используем функцию localstorage.getItem().
Для просмотра всех изображения применим функцию window.localstorage.length().
function showImages() {
for (let i = 0; i < window.localStorage.length; i++) {
let res = window.localStorage.getItem(window.localStorage.key(i));
}
}
Шаг 6
Затем сохраним в переменной res все изображения, которые нужно отобразить. Для вывода изображений создадим новый тег <img> с помощью функции Image().
function showImages() {
for (let i = 0; i < window.localStorage.length; i++) {
let res = window.localStorage.getItem(window.localStorage.key(i));
var image = new Image();
image.src = res;
}
}
Шаг 7
Для отображения созданных элементов используем функцию append(image). Создадим блок div с идентификатором preview.
<div id="preview">
</div>
Шаг 8
Теперь изменим код функции showImages():
function showImages() {
for (let i = 0; i < window.localStorage.length; i++) {
let res = window.localStorage.getItem(window.localStorage.key(i));
var image = new Image();
image.src = res;
document.body.append(image);
}
}
Шаг 9
Зададим стили <img>:
img{
height: 250px;
border-radius: 10px;
box-shadow: 0 0 1.2rem rgba(0,0,0,.25);
margin: 10px;
}
Но как только вы нажмете кнопку «Показать изображения», будет добавлен <img> с тем же изображением. Поэтому теперь необходимо проверить, существует ли этот тег.
function showImages() {
var img = document.getElementById("img");
var parentDiv = document.getElementById('preview');
if (parentDiv.contains(img)) {
parentDiv.prepend(img);
} else if (parentDiv.contains(img) == false) {
for (let i = 0; i < window.localStorage.length; i++) {
let res = window.localStorage.getItem(window.localStorage.key(i));
var image = new Image();
image.src = res;
image.setAttribute('id', 'img');
parentDiv.append(image);
}
}
Теперь реализуем удаление изображения. Для этого потребуется кнопка, которую мы создадим с помощью createElement().
Шаг 10
Затем добавим вызов функции, которая принимает имя удаляемого изображения в качестве аргумента.
function showImages() {
var img = document.getElementById("img");
var parentDiv = document.getElementById('preview');
if (parentDiv.contains(img)) {
parentDiv.prepend(img);
} else if (parentDiv.contains(img) == false) {
for (let i = 0; i < window.localStorage.length; i++) {
let res = window.localStorage.getItem(window.localStorage.key(i));
var image = new Image();
var button = document.createElement("button");
button.innerHTML = "Delete";
button.setAttribute('class' , 'deleteButton');
button.setAttribute('onclick',DeleteImage('${window.localStorage.key(i)}')`);
image.src = res;
image.setAttribute('id', 'img');
parentDiv.append(image);
parentDiv.append(button);
}
}
Теперь кнопка удаления отображается для каждого изображения. Добавим к ней стили deleteButton.
.deleteButton{
border: 0;
background-color: rgb(236, 81, 81);
color: white;
border-radius: 50px;
cursor: pointer;
transition: .25s all;
height: 50px;
margin: 10px auto;
}
С помощью функции localstorage.removeItem можно удалить пару ключ и значение.
Мы реализовали наглядный пример сохранения изображений на стороне клиента с помощью localStorage.