Skip to content

Commit b042767

Browse files
committed
[CON-19/compl] conclusion
Solving 3 tasks. Working with "DOM/events", arr meth's. Worth noting: - all this interview (note the solutions). FS-dev: B-3 / JS basic
1 parent 8ec0555 commit b042767

File tree

3 files changed

+168
-1
lines changed

3 files changed

+168
-1
lines changed

full-stack-dev/3-js-basic/19-conclusion/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
</head>
1111

1212
<body>
13+
<ul class="todo-list" id="todo-list"></ul>
14+
15+
<ul id="product-list">
16+
<li class="product-item">Молоко</li>
17+
<li class="product-item">Хлеб</li>
18+
<li class="product-item">Масло</li>
19+
<li class="product-item">Сыр</li>
20+
</ul>
1321
</body>
1422

1523
</html>
Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,151 @@
11
'use strict';
22

3-
// Задание 1:
3+
// ** Задание 1:
4+
// Представь, что мы делаем простой "To-Do" лист.
5+
// Напиши одну функцию createTodoItem(text). Эта функция должна:
6+
// 1. Принимать один аргумент — text (строка, текст задачи).
7+
// 2. Создавать новый DOM-элемент <li>.
8+
// 3. Внутрь <li> помещать:
9+
// - Сам text (безопасным способом).
10+
// - Элемент <button> с текстом "Удалить".
11+
// 4. При клике на эту кнопку "Удалить" — весь элемент <li> должен удаляться из DOM.
12+
// 5. Функция должна возвращать (return) созданный и настроенный элемент <li>.
13+
14+
const todoList = document.getElementById('todo-list');
15+
16+
function createTodoItem(text) {
17+
if (!text || typeof text !== 'string') {
18+
return;
19+
}
20+
21+
const todoItem = document.createElement('li');
22+
todoItem.classList.add('todo-item');
23+
todoItem.setAttribute('id', 'todo-item');
24+
todoItem.textContent = text.trim();
25+
26+
const todoBtn = document.createElement('button');
27+
todoBtn.classList.add('todo-btn');
28+
todoBtn.setAttribute('id', 'todo-btn');
29+
todoBtn.textContent = 'Удалить';
30+
31+
todoItem.append(todoBtn);
32+
33+
todoBtn.addEventListener('click', () => {
34+
todoItem.remove();
35+
});
36+
37+
return todoItem;
38+
}
39+
40+
todoList.append(createTodoItem('Погулять с собакой')); // создание элемента и сразу добавление
41+
42+
// ** Задание 2:
43+
// Я — твой тимлид. Я вижу, что другой 'джун' написал код для интерактивного списка продуктов. Код работает, но у меня к нему есть претензии.
44+
// Вот его Html:
45+
/*
46+
<ul id="product-list">
47+
<li onclick="selectProduct(this)">Молоко</li>
48+
<li onclick="selectProduct(this)">Хлеб</li>
49+
<li onclick="selectProduct(this)">Масло</li>
50+
<li onclick="selectProduct(this)">Сыр</li>
51+
</ul>
52+
*/
53+
// Вот его JS:
54+
/* function selectProduct(element) {
55+
// Сначала убираем 'selected' у всех
56+
const allItems = document.querySelectorAll('#product-list li');
57+
for (let i = 0; i < allItems.length; i++) {
58+
allItems[i].classList.remove('selected');
59+
}
60+
61+
// Добавляем 'selected' тому, по которому кликнули
62+
element.classList.add('selected');
63+
}*/
64+
// Твоя задача — проанализировать этот код:
65+
// 1. Какие концептуальные проблемы ты видишь в HTML?.
66+
// 2. Какие проблемы с производительностью создает этот подход (и в JS, и в HTML), если в списке будет 1000 элементов?
67+
// 3. Как бы ты полностью переписал этот код (и HTML, и JS), используя паттерн делегирования событий, чтобы он был чистым и эффективным?
68+
69+
const productList = document.getElementById('product-list');
70+
const productItems = document.querySelectorAll('.product-item');
71+
72+
function selectProduct(event) {
73+
const target = event.target;
74+
75+
// Шаг 1: Убедимся, что кликнули по LI
76+
if (target.tagName !== 'LI') {
77+
return;
78+
}
79+
80+
// Шаг 2: (Опционально) Если кликнули по уже выбранному, ничего не делаем
81+
if (target.classList.contains('selected')) {
82+
return;
83+
}
84+
85+
// Шаг 3: Находим *текущий* выбранный элемент (если он есть)
86+
// Это очень быстрый поиск, который ищет только *один* элемент
87+
const currentSelected = productList.querySelector('.selected');
88+
89+
// Шаг 4: Снимаем с него класс
90+
if (currentSelected) {
91+
currentSelected.classList.remove('selected');
92+
}
93+
94+
// Шаг 5: Добавляем класс цели
95+
target.classList.add('selected');
96+
}
97+
98+
productList.addEventListener('click', selectProduct);
99+
100+
// ? альтернативное решение для multi-выбора (с возможность отметил/убрал зачёркивание)
101+
// function selectProducts(event) {
102+
// const target = event.target;
103+
//
104+
// if (target.tagName !== 'LI') {
105+
// return;
106+
// }
107+
//
108+
// target.classList.toggle('selected');
109+
// }
110+
//
111+
// productList.addEventListener('click', selectProducts);
112+
113+
// ** Задание 3:
114+
// Задача: Напиши функцию getPositiveReviews(reviewsArray), которая в одну цепочку (chaining) делает следующее:
115+
// 1. Отфильтровывает "плохие" отзывы: оставляет только те, у которых rating >= 4.
116+
// 2. Отфильтровывает "пустые" отзывы: оставляет только те, у которых text — это не null и не пустая строка (после trim()'а).
117+
// 3. Преобразует (маппирует) оставшиеся объекты в строки вида: ID 1: Отличный товар!
118+
// 4 .Функция должна вернуть новый массив этих строк.
119+
// Ожидаемый результат для reviews: [ "ID 1: Отличный товар!", "ID 3: Неплохо, но могло быть лучше.", "ID 5: Просто супер" ]
120+
/*
121+
const reviews = [
122+
{ id: 1, text: 'Отличный товар!', rating: 5 },
123+
{ id: 2, text: ' ', rating: 3 }, // Пустой текст
124+
{ id: 3, text: 'Неплохо, но могло быть лучше.', rating: 4 },
125+
{ id: 4, text: 'Ужасно.', rating: 1 },
126+
{ id: 5, text: 'Просто супер', rating: 5 },
127+
{ id: 6, text: null, rating: 2 }, // null вместо текста
128+
];
129+
*/
130+
131+
const reviews = [
132+
{ id: 1, text: 'Отличный товар!', rating: 5 },
133+
{ id: 2, text: ' ', rating: 3 }, // Пустой текст
134+
{ id: 3, text: 'Неплохо, но могло быть лучше.', rating: 4 },
135+
{ id: 4, text: 'Ужасно.', rating: 1 },
136+
{ id: 5, text: 'Просто супер', rating: 5 },
137+
{ id: 6, text: null, rating: 2 }, // null вместо текста
138+
];
139+
140+
function getPositiveReviews(reviewsArray = []) {
141+
if (!reviewsArray) {
142+
return [];
143+
}
144+
145+
return reviewsArray
146+
.filter((review) => review.rating >= 4)
147+
.filter((review) => review.text !== null && review.text.trim() !== '')
148+
.map((review) => `ID ${review.id}: ${review.text}`);
149+
}
150+
151+
console.log(getPositiveReviews(reviews)); //  ['ID 1: Отличный товар!', 'ID 3: Неплохо, но могло быть лучше.', 'ID 5: Просто супер']
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1+
.todo-btn {
2+
margin-left: 10px;
3+
cursor: pointer;
4+
}
15

6+
.product-item {
7+
cursor: pointer;
8+
}
9+
10+
.selected {
11+
text-decoration: line-through;
12+
}

0 commit comments

Comments
 (0)