Skip to content

Commit 6a46fe8

Browse files
committed
[LES-17.6/st-compl] working-with-attributes
Intro to "get/setAttribute()" meth's. Practice with "dataset" prop. Worth noting: - all this lesson/practice (note the solutions). FS-dev: B-3 / JS basic
1 parent e73090a commit 6a46fe8

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
<div class="counter-container">
14+
<button id="decreaseBtn">-</button>
15+
<span id="counter" data-value="0">0</span>
16+
<button id="increaseBtn">+</button>
17+
</div>
18+
19+
<div>
20+
<button id="toggleBtn">Показать</button>
21+
<div id="spoiler" data-state="hidden" style="display: none;">
22+
Этот текст изначально скрыт.
23+
</div>
24+
</div>
25+
26+
<div>
27+
<h4>Категории:</h4>
28+
<div id="filter-controls">
29+
<button data-filter="all">Все</button>
30+
<button data-filter="fruit">Фрукты</button>
31+
<button data-filter="vegetable">Овощи</button>
32+
</div>
33+
34+
<h4>Список:</h4>
35+
<ul id="item-list">
36+
<li data-category="fruit">Апельсин</li>
37+
<li data-category="vegetable">Картофель</li>
38+
<li data-category="fruit">Банан</li>
39+
<li data-category="vegetable">Помидор</li>
40+
<li data-category="fruit">Киви</li>
41+
</ul>
42+
</div>
43+
</body>
44+
45+
</html>
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
'use strict';
2+
3+
// Задание 1:
4+
// Нужно создать простой счётчик, значение которого хранится прямо в HTML.
5+
/*
6+
<div>
7+
<button id="decreaseBtn">-</button>
8+
<span id="counter" data-value="0">0</span>
9+
<button id="increaseBtn">+</button>
10+
</div>
11+
*/
12+
// Твоя задача — написать JavaScript код, который:
13+
// 1. Находит все три элемента: две кнопки и span.
14+
// 2. При клике на кнопку + (increaseBtn):
15+
// - Считывает текущее значение из data-value у span.
16+
// - Увеличивает его на единицу.
17+
// - Записывает новое значение обратно в data-value и в текстовое содержимое span.
18+
// При клике на кнопку - (decreaseBtn) делает то же самое, но уменьшает значение на единицу.
19+
20+
const counterContainer = document.querySelector('.counter-container');
21+
const counter = document.querySelector('#counter');
22+
const decreaseBtn = document.querySelector('#decreaseBtn');
23+
const increaseBtn = document.querySelector('#increaseBtn');
24+
25+
function updateCounter(event) {
26+
const target = event.target;
27+
let countValue = Number(counter.dataset.value);
28+
29+
if (target.tagName === 'BUTTON') {
30+
if (target.id === 'decreaseBtn') {
31+
countValue--;
32+
counter.dataset.value = countValue;
33+
counter.textContent = countValue;
34+
} else if (target.id === 'increaseBtn') {
35+
countValue++;
36+
counter.dataset.value = countValue;
37+
counter.textContent = countValue;
38+
}
39+
}
40+
}
41+
42+
counterContainer.addEventListener('click', updateCounter);
43+
44+
// ?? альтернативное решение (более прямолинейное)
45+
increaseBtn.addEventListener('click', () => {
46+
let currentValue = Number(counter.dataset.value);
47+
currentValue++;
48+
counter.dataset.value = currentValue;
49+
counter.textContent = currentValue;
50+
});
51+
52+
decreaseBtn.addEventListener('click', () => {
53+
let currentValue = Number(counter.dataset.value);
54+
currentValue--;
55+
counter.dataset.value = currentValue;
56+
counter.textContent = currentValue;
57+
});
58+
59+
// Задание 2:
60+
// Нужно использовать data- атрибут для управления состоянием элемента.
61+
/*
62+
<div>
63+
<button id="toggleBtn">Показать</button>
64+
<div id="spoiler" data-state="hidden" style="display: none;">
65+
Этот текст изначально скрыт.
66+
</div>
67+
</div>
68+
*/
69+
// Твоя задача — написать JavaScript код, который:
70+
// 1. При клике на кнопку toggleBtn проверяет значение атрибута data-state у элемента spoiler.
71+
// 2. Если значение равно "hidden":
72+
// - Меняет его на "visible".
73+
// - Показывает элемент spoiler (например, через spoiler.style.display = 'block').
74+
// - Меняет текст на кнопке на "Скрыть".
75+
// 3. Если значение равно "visible":
76+
// - Меняет его на "hidden".
77+
// - Скрывает элемент spoiler (через spoiler.style.display = 'none').
78+
// - Меняет текст на кнопке обратно на "Показать".
79+
80+
const toggleBtn = document.querySelector('#toggleBtn');
81+
const spoiler = document.querySelector('#spoiler');
82+
83+
function changeVisible() {
84+
let state = spoiler.dataset.state;
85+
86+
if (state === 'hidden') {
87+
spoiler.dataset.state = 'visible';
88+
spoiler.style.display = 'block';
89+
toggleBtn.textContent = 'Скрыть';
90+
} else if (state === 'visible') {
91+
spoiler.dataset.state = 'hidden';
92+
spoiler.style.display = 'none';
93+
toggleBtn.textContent = 'Показать';
94+
}
95+
}
96+
97+
toggleBtn.addEventListener('click', changeVisible);
98+
99+
// ?? альтернативное решение (DRY)
100+
toggleBtn.addEventListener('click', () => {
101+
// Проверяем текущее состояние
102+
const isHidden = spoiler.dataset.state === 'hidden';
103+
104+
// Обновляем состояние и стили
105+
spoiler.dataset.state = isHidden ? 'visible' : 'hidden';
106+
spoiler.style.display = isHidden ? 'block' : 'none';
107+
108+
// Обновляем текст кнопки
109+
toggleBtn.textContent = isHidden ? 'Скрыть' : 'Показать';
110+
});
111+
112+
// Задание 3:
113+
// Сделать интерактивный фильтр для списка, используя data- атрибуты.
114+
/*
115+
<div>
116+
<h4>Категории:</h4>
117+
<div id="filter-controls">
118+
<button data-filter="all">Все</button>
119+
<button data-filter="fruit">Фрукты</button>
120+
<button data-filter="vegetable">Овощи</button>
121+
</div>
122+
123+
<h4>Список:</h4>
124+
<ul id="item-list">
125+
<li data-category="fruit">Апельсин</li>
126+
<li data-category="vegetable">Картофель</li>
127+
<li data-category="fruit">Банан</li>
128+
<li data-category="vegetable">Помидор</li>
129+
<li data-category="fruit">Киви</li>
130+
</ul>
131+
</div>
132+
*/
133+
// Твоя задача — написать JavaScript код, который:
134+
// 1. Находит все кнопки-фильтры и все элементы списка <li>.
135+
// 2. Добавляет один обработчик событий (лучше всего на родительский div filter-controls, используя делегирование, как ты делал в первой задаче) на клики по кнопкам.
136+
// 3. При клике на кнопку:
137+
// - Получает значение её атрибута data-filter (например, "fruit").
138+
// - Проходит по всем элементам списка <li>.
139+
// - Для каждого элемента <li> сравнивает его data-category со значением из data-filter кнопки.
140+
// - Если data-filter на кнопке равен "all" ИЛИ data-category элемента совпадает с data-filter кнопки, элемент <li> должен быть виден.
141+
// - В противном случае элемент <li> должен быть скрыт.
142+
143+
const filterControls = document.querySelector('#filter-controls');
144+
const allItems = document.querySelectorAll('li[data-category]');
145+
146+
function interactiveFilter(event) {
147+
const target = event.target;
148+
149+
if (target.tagName === 'BUTTON') {
150+
const filter = target.dataset.filter;
151+
152+
allItems.forEach((item) => {
153+
const category = item.dataset.category;
154+
155+
if (filter === 'all' || category === filter) {
156+
item.style.display = 'list-item'; // именно list-item, а не block (т.к. у списков другое отображение.. а то ul "точки" пропадут)
157+
} else {
158+
item.style.display = 'none'; // а здесь, none.. подходит, стандартно
159+
}
160+
});
161+
}
162+
}
163+
164+
filterControls.addEventListener('click', interactiveFilter);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.counter-container {
2+
margin-bottom: 10px;
3+
}

0 commit comments

Comments
 (0)