Skip to content

Commit 808b857

Browse files
committed
[LES-17.9/st-compl] intro-to-localStorage
Practice with "localStorage", with "adding/getting/deleting" data. Worth noting: - all this lesson/practice (note the solutions). FS-dev: B-3 / JS basic
1 parent f79147c commit 808b857

File tree

7 files changed

+299
-0
lines changed

7 files changed

+299
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<title>DOM</title>
9+
<link rel="stylesheet" href="./styles.css">
10+
<script src="./index.js" defer></script>
11+
</head>
12+
13+
<body style="background-color: #1c1b21; text-align: center">
14+
<img src="./logo.svg" alt>
15+
<div class="panel">I love this!</div>
16+
<div class="input-wrap">
17+
<input class="input" id="input">
18+
<button class="button">Change</button>
19+
</div>
20+
<div class="notification notification_hide">Changed!</div>
21+
<div class="new-panel panel"></div>
22+
</body>
23+
24+
</html>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict';
2+
3+
const panelMessage = document.querySelector('.panel');
4+
const input = document.querySelector('.input');
5+
const button = document.querySelector('.button');
6+
const notificationMessage = document.querySelector('.notification');
7+
let notificationTimer; // переменная для хранения ID таймера
8+
9+
// DRY
10+
function changeMessage() {
11+
const inputValue = input.value;
12+
13+
if (!inputValue) {
14+
return;
15+
}
16+
17+
panelMessage.textContent = inputValue;
18+
input.value = '';
19+
notificationMessage.classList.remove('notification_hide');
20+
21+
// очищаем предыдущий таймер
22+
clearTimeout(notificationTimer);
23+
24+
// устанавливаем новый таймер (заносим в переменную ID таймера)
25+
notificationTimer = setTimeout(() => {
26+
notificationMessage.classList.add('notification_hide');
27+
}, 1000);
28+
}
29+
30+
// изменения сообщения через "click" по кнопке
31+
function changeMessageByClick() {
32+
changeMessage();
33+
}
34+
35+
button.addEventListener('click', changeMessageByClick);
36+
37+
// изменения сообщения через "keydown/Enter" в поле input
38+
function changeMessageByKeydown(event) {
39+
// без объекта event не обойтись, т.к. в нём определяем code кнопки.. "Enter"
40+
if (event.code === 'Enter') {
41+
changeMessage();
42+
}
43+
}
44+
45+
input.addEventListener('keydown', changeMessageByKeydown);
46+
47+
// создание/добавление "нового" Html элемента/узла
48+
const newPanel = document.querySelector('.new-panel');
49+
const message = document.createElement('p');
50+
51+
message.classList.add('panel-message');
52+
message.setAttribute('id', 'panel-message');
53+
message.textContent = 'Lets do it!';
54+
55+
newPanel.append(message);
56+
57+
// работа с localStorage
58+
localStorage.setItem('task-1', 'Поиграть в PS'); // ключ - значение
59+
localStorage.setItem('task-2', 1); // разные типы значений
60+
localStorage.setItem('task-3', true);
61+
62+
const task2 = localStorage.getItem('task-2');
63+
console.log(typeof task2); // "string" - всегда будет.. как бы не выглядело значение
64+
65+
localStorage.removeItem('task-2');
66+
// localStorage.clear();
Lines changed: 25 additions & 0 deletions
Loading
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>DOM - practice</title>
8+
<link rel="stylesheet" href="./style.css">
9+
<script src="./practice.js" defer></script>
10+
</head>
11+
12+
<body>
13+
</body>
14+
15+
</html>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'use strict';
2+
3+
// Задание 1:
4+
// Сделать так, чтобы сайт "запоминал" выбранную пользователем тёмную тему.
5+
// Условия:
6+
// - Представь, что у тебя есть готовый HTML и CSS. В CSS уже есть класс dark-theme, который при добавлении к элементу <body> включает тёмное оформление.
7+
// - Тебе нужно написать JavaScript-код, который будет выполняться при каждой загрузке страницы.
8+
// Задание:
9+
// При загрузке страницы твой скрипт должен проверить, есть ли в localStorage значение по ключу 'theme'.
10+
// Если по этому ключу лежит строка 'dark', скрипт должен найти <body> и добавить ему класс dark-theme.
11+
12+
localStorage.setItem('theme', 'dark');
13+
14+
// const body = document.querySelector('body');
15+
const body = document.body; // а можно вот так.. сразу/напрямую
16+
17+
function checkPageTheme() {
18+
const theme = localStorage.getItem('theme');
19+
20+
if (theme && theme === 'dark') {
21+
body.classList.add('dark-theme');
22+
}
23+
}
24+
25+
checkPageTheme();
26+
27+
// Задание 2:
28+
// Написать функцию, которая добавляет новую задачу в список дел и сохраняет весь обновлённый список в localStorage. Это основа любого to-do приложения.
29+
// Задание:
30+
// Напиши функцию с названием addTask, которая принимает один аргумент — текст новой задачи (taskText).
31+
// Эта функция должна:
32+
// 1. Получить из localStorage по ключу 'tasks' текущий список задач.
33+
// 2. Важный момент: localStorage вернёт либо JSON-строку (если задачи уже есть), либо null (если это первая задача). Твой код должен правильно обработать оба случая. Если вернулся null, нужно считать, что изначально у нас пустой массив [].
34+
// 3. Преобразовать полученную JSON-строку обратно в массив.
35+
// 4. Добавить в конец этого массива новую задачу (taskText).
36+
// 5. Преобразовать обновлённый массив снова в JSON-строку.
37+
// 6. Сохранить эту строку обратно в localStorage по тому же ключу 'tasks'.
38+
39+
function addTask(taskText) {
40+
if (!taskText || typeof taskText !== 'string') {
41+
return;
42+
}
43+
44+
const tasks = localStorage.getItem('tasks');
45+
46+
if (tasks === null) {
47+
const todo = [];
48+
49+
todo.push(taskText);
50+
localStorage.setItem('tasks', JSON.stringify(todo));
51+
52+
return todo;
53+
} else {
54+
const storageTodo = JSON.parse(tasks);
55+
56+
if (!storageTodo.includes(taskText)) {
57+
storageTodo.push(taskText);
58+
localStorage.setItem('tasks', JSON.stringify(storageTodo));
59+
}
60+
61+
return storageTodo;
62+
}
63+
}
64+
65+
console.log(addTask('Погулять с собакой')); // ['Убрать в квартире']
66+
console.log(addTask('Убрать в квартире')); // ['Убрать в квартире', 'Погулять с собакой']
67+
68+
// ?? альтернативное решение
69+
function addNewTask(taskText) {
70+
if (!taskText || typeof taskText !== 'string') {
71+
return;
72+
}
73+
74+
let currentTasks = JSON.parse(localStorage.getItem('tasks')) || []; // хитрый способ получить массив или пустой массив в одну строку
75+
76+
if (!currentTasks.includes(taskText)) {
77+
currentTasks.push(taskText);
78+
localStorage.setItem('tasks', JSON.stringify(currentTasks));
79+
}
80+
81+
return currentTasks;
82+
}
83+
84+
// Задание 3:
85+
// Напиши функцию removeTask, которая принимает один аргумент — текст задачи, которую нужно удалить (taskText).
86+
// Эта функция должна:
87+
// 1. Получить массив задач из localStorage (не забывая про JSON.parse и проверку на null).
88+
// 2. Если массив существует и он не пустой, удалить из него элемент, который в точности совпадает с taskText.
89+
// 3. Сохранить изменённый массив (уже без удалённой задачи) обратно в localStorage.
90+
// Подсказка: для удаления элемента из массива по значению очень удобно использовать метод .filter(). Он позволяет создать новый массив со всеми элементами, которые проходят проверку
91+
92+
function removeTask(taskText) {
93+
if (!taskText || typeof taskText !== 'string') {
94+
return;
95+
}
96+
97+
const storageTodo = JSON.parse(localStorage.getItem('tasks'));
98+
99+
if (storageTodo && storageTodo.length > 0) {
100+
const newTasks = storageTodo.filter((task) => task !== taskText);
101+
localStorage.setItem('tasks', JSON.stringify(newTasks));
102+
103+
return newTasks;
104+
}
105+
}
106+
107+
console.log(removeTask('Убрать в квартире')); // ['Погулять с собакой']
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.dark-theme {
2+
color: black;
3+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
.panel {
2+
margin-bottom: 20px;
3+
border-radius: 10px;
4+
padding: 40px;
5+
font-size: 18px;
6+
color: white;
7+
background: rgba(255, 255, 255, .05);
8+
}
9+
10+
.input-wrap {
11+
margin-bottom: 20px;
12+
}
13+
14+
.input {
15+
border: 1px solid rgba(212, 212, 212, .05);
16+
border-radius: 10px;
17+
padding: 15px 16px;
18+
height: 56px;
19+
box-sizing: border-box;
20+
font-size: 18px;
21+
line-height: 21px;
22+
color: white;
23+
box-shadow: none;
24+
outline: none;
25+
background: rgba(255, 255, 255, .05);
26+
}
27+
28+
.button {
29+
display: inline-flex;
30+
justify-content: center;
31+
align-items: center;
32+
border: none;
33+
border-radius: 10px;
34+
padding: 20px 40px;
35+
box-sizing: border-box;
36+
text-align: center;
37+
color: white;
38+
background: #6c38cc;
39+
cursor: pointer;
40+
transition: all .2s;
41+
}
42+
43+
.button:hover {
44+
background-color: #844fe6;
45+
}
46+
47+
.notification {
48+
margin-bottom: 20px;
49+
font-size: 16px;
50+
color: white;
51+
}
52+
53+
.notification_hide {
54+
display: none;
55+
}
56+
57+
.panel-message {
58+
margin: 0;
59+
}

0 commit comments

Comments
 (0)