Skip to content

Introduction to browser events #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
a11e2a3
Objects
Regnised Aug 14, 2021
d073b92
Merge branch 'javascript-tutorial:master' into master
Regnised Aug 14, 2021
6f63dff
Update 1-js/04-object-basics/01-object/2-hello-object/task.md
Regnised Aug 15, 2021
690516f
Update 1-js/04-object-basics/01-object/3-is-empty/task.md
Regnised Aug 15, 2021
d1d20f9
Update 1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/te…
Regnised Aug 15, 2021
126b55b
Update 1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/te…
Regnised Aug 15, 2021
1808c2f
Update 1-js/04-object-basics/01-object/article.md
Regnised Aug 15, 2021
b7f4746
Update 1-js/04-object-basics/01-object/article.md
Regnised Aug 15, 2021
c31ff51
Update 1-js/04-object-basics/01-object/2-hello-object/task.md
tarasyyyk Aug 15, 2021
68d53eb
Update 1-js/04-object-basics/01-object/2-hello-object/task.md
tarasyyyk Aug 15, 2021
019602e
Update 1-js/04-object-basics/01-object/2-hello-object/task.md
tarasyyyk Aug 15, 2021
550b1fb
Objects
Regnised Aug 23, 2021
787568b
Merge branch 'master' of github.com:Regnised/uk.javascript.info
Regnised Aug 23, 2021
82f0f9a
Merge branch 'javascript-tutorial:master' into master
Regnised Aug 23, 2021
cbda1c0
Update 1-js/05-data-types/05-array-methods/1-camelcase/task.md
tarasyyyk Aug 23, 2021
3f73a4b
Update 1-js/05-data-types/05-array-methods/10-average-age/task.md
Regnised Aug 24, 2021
007d5ac
Update 1-js/05-data-types/05-array-methods/11-array-unique/solution.md
Regnised Aug 24, 2021
0a58cb5
Update 1-js/05-data-types/05-array-methods/12-reduce-object/task.md
Regnised Aug 24, 2021
15efbc0
Update 1-js/05-data-types/05-array-methods/9-shuffle/task.md
Regnised Aug 24, 2021
7758975
Update 1-js/05-data-types/05-array-methods/9-shuffle/solution.md
Regnised Aug 24, 2021
ca0c3b0
Update 1-js/05-data-types/05-array-methods/2-filter-range/task.md
Regnised Aug 24, 2021
86fccb4
Update 1-js/05-data-types/05-array-methods/2-filter-range/task.md
Regnised Aug 24, 2021
1ea7283
Update 1-js/05-data-types/05-array-methods/3-filter-range-in-place/ta…
Regnised Aug 24, 2021
676d942
Update 1-js/05-data-types/05-array-methods/7-map-objects/task.md
Regnised Aug 24, 2021
eff8fea
Add translate
Regnised Aug 24, 2021
5cb6b18
Merge branch 'master' of github.com:Regnised/uk.javascript.info
Regnised Aug 24, 2021
4a1c393
Merge branch 'javascript-tutorial:master' into master
Regnised Aug 24, 2021
c987f1d
Update 1-js/05-data-types/05-array-methods/9-shuffle/solution.md
tarasyyyk Aug 25, 2021
b5a26f7
Update 1-js/05-data-types/05-array-methods/9-shuffle/solution.md
tarasyyyk Aug 25, 2021
163d7e6
Merge branch 'javascript-tutorial:master' into master
Regnised Dec 6, 2021
3063331
Promisification
Regnised Dec 7, 2021
ca8f7bb
Merge branch 'javascript-tutorial:master' into master
Regnised Dec 9, 2021
4684a0d
Modules, introduction
Regnised Dec 20, 2021
9266f24
Merge branch 'javascript-tutorial:master' into master
Regnised Dec 20, 2021
3b740f2
Apply suggestions from code review
tarasyyyk Dec 21, 2021
bda1c77
Merge branch 'javascript-tutorial:master' into master
Regnised Dec 21, 2021
5777c31
Merge branch 'javascript-tutorial:master' into master
Regnised Jan 5, 2022
599737f
Merge branch 'javascript-tutorial:master' into master
Regnised Jan 12, 2022
cdf34ab
Merge branch 'javascript-tutorial:master' into master
Regnised Jan 25, 2022
bee8302
feat: Introduction to browser events
Regnised Jan 25, 2022
8e473d3
Update 2-ui/2-events/01-introduction-browser-events/01-hide-other/tas…
Regnised Feb 7, 2022
d5f632e
Update 2-ui/2-events/01-introduction-browser-events/01-hide-other/tas…
Regnised Feb 7, 2022
c0286d4
Update 2-ui/2-events/01-introduction-browser-events/01-hide-other/tas…
Regnised Feb 7, 2022
e1ae78c
Update 2-ui/2-events/01-introduction-browser-events/02-hide-self-oncl…
Regnised Feb 7, 2022
2397c96
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
ef0bd68
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
2c446c1
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
b3cabe4
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
9321de2
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
5ac3d87
Update 2-ui/2-events/01-introduction-browser-events/04-move-ball-fiel…
Regnised Feb 7, 2022
23c6012
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/s…
Regnised Feb 7, 2022
a092cc6
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/s…
Regnised Feb 7, 2022
8d4eba5
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/s…
Regnised Feb 7, 2022
7f57848
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/t…
Regnised Feb 7, 2022
f73b996
Update 2-ui/2-events/01-introduction-browser-events/article.md
Regnised Feb 7, 2022
712918a
Update 2-ui/2-events/01-introduction-browser-events/article.md
Regnised Feb 7, 2022
89acea9
Update 2-ui/2-events/01-introduction-browser-events/article.md
Regnised Feb 7, 2022
53a2b30
Update 2-ui/2-events/01-introduction-browser-events/article.md
Regnised Feb 7, 2022
6d97cea
Update 2-ui/2-events/01-introduction-browser-events/article.md
dolgachio Feb 15, 2022
9efb2eb
Update 2-ui/2-events/01-introduction-browser-events/01-hide-other/tas…
dolgachio Feb 15, 2022
f4bb145
Update 2-ui/2-events/01-introduction-browser-events/02-hide-self-oncl…
dolgachio Feb 15, 2022
dc40c13
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/t…
Regnised Feb 19, 2022
caef75f
Update 2-ui/2-events/01-introduction-browser-events/03-which-handlers…
Regnised Feb 19, 2022
274b155
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/t…
Regnised Feb 19, 2022
2605ab6
Update 2-ui/2-events/01-introduction-browser-events/05-sliding-menu/t…
Regnised Feb 19, 2022
7da7a93
Update 2-ui/2-events/01-introduction-browser-events/06-hide-message/s…
Regnised Feb 19, 2022
dbf1f1b
Update 2-ui/2-events/01-introduction-browser-events/06-hide-message/s…
Regnised Feb 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

<body>

<input type="button" id="hider" value="Click to hide the text" />
<input type="button" id="hider" value="Натисніть, щоб текст зник" />

<div id="text">Text</div>
<div id="text">Текст</div>

<script>
// Here it doesn't matter how we hide the text,
// could also use style.display:
// Тут не має значення, як ми приховуємо текст
// Також можна використати style.display:
document.getElementById('hider').onclick = function() {
document.getElementById('text').hidden = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

<body>

<input type="button" id="hider" value="Click to hide the text" />
<input type="button" id="hider" value="Натисніть, щоб текст зник" />

<div id="text">Text</div>
<div id="text">Текст</div>

<script>
/* your code */
/* ваш код */
</script>

</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 5

---

# Hide on click
# Приховати елемент після натискання кнопки

Add JavaScript to the `button` to make `<div id="text">` disappear when we click it.
Напишіть такий JavaScript, щоб після натискання на кнопку `button`, елемент `<div id="text">` зникав.

The demo:
Демонстрація роботи:

[iframe border=1 src="solution" height=80]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Can use `this` in the handler to reference "the element itself" here:
Можемо використати `this` в обробнику для доступу до самого елемента:

```html run height=50
<input type="button" onclick="this.hidden=true" value="Click to hide">
<input type="button" onclick="this.hidden=true" value="Сховати">
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Hide self
# Сховати себе

Create a button that hides itself on click.
Напишіть такий код, щоб після натискання на кнопку, вона зникала.

```online
Like this:
<input type="button" onclick="this.hidden=true" value="Click to hide">
Наприклад:
<input type="button" onclick="this.hidden=true" value="Сховати">
```
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
The answer: `1` and `2`.
Відповідь: `1` і `2`.

The first handler triggers, because it's not removed by `removeEventListener`. To remove the handler we need to pass exactly the function that was assigned. And in the code a new function is passed, that looks the same, but is still another function.
Перший обробник спрацює, тому що він не був вилучений методом `removeEventListener`. Щоб видалити обробник, необхідно передати саме ту функцію, яка була призначена як обробник. Попри те, що код ідентичний, в `removeEventListener` передається нова, інша функція.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Перший обробник спрацює, тому що він не був вилучений методом `removeEventListener`. Щоб видалити обробник, необхідно передати саме ту функцію, яка була призначена як обробник. Попри те, що код ідентичний, в `removeEventListener` передається нова, інша функція.
Перший обробник спрацює, тому що він не був видалений методом `removeEventListener`. Щоб видалити обробник, необхідно передати саме ту функцію, яка була призначена як обробник. Попри те, що код ідентичний, в `removeEventListener` передається нова, інша функція.


To remove a function object, we need to store a reference to it, like this:
Щоб видалити функцію-обробник, потрібно десь зберегти посилання на неї, наприклад:

```js
function handler() {
Expand All @@ -13,4 +13,4 @@ button.addEventListener("click", handler);
button.removeEventListener("click", handler);
```

The handler `button.onclick` works independently and in addition to `addEventListener`.
Обробник `button.onclick` спрацює все одно. Разом з `addEventListener`.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
importance: 5
важливість: 5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
важливість: 5
importance: 5


---

# Which handlers run?
# Який обробник запуститься?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Який обробник запуститься?
# Який обробник буде запущено?


There's a button in the variable. There are no handlers on it.
У змінній `button` знаходиться кнопка. Спочатку на ній немає обробників.

Which handlers run on click after the following code? Which alerts show up?
Який з обробників запуститься? Що буде виведено під час кліку після виконання коду?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Який з обробників запуститься? Що буде виведено під час кліку після виконання коду?
Який обробник буде запущено? Що буде виведено під час кліку після виконання коду?


```js no-beautify
button.addEventListener("click", () => alert("1"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

First we need to choose a method of positioning the ball.
Спочатку ми маємо вибрати метод позиціювання м’яча.

We can't use `position:fixed` for it, because scrolling the page would move the ball from the field.
Ми не можемо використати `position:fixed` для цього, оскільки прокручування сторінки переміщатиме м’яч поля.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Ми не можемо використати `position:fixed` для цього, оскільки прокручування сторінки переміщатиме м’яч поля.
Ми не можемо використати `position:fixed` для цього, оскільки прокручування сторінки переміщатиме м’яч від поля.


So we should use `position:absolute` and, to make the positioning really solid, make `field` itself positioned.
Правильніше використовувати `position:absolute` і, щоб зробити позиціювання справді надійним, зробимо саме поле `field` позиціонованим.

Then the ball will be positioned relatively to the field:
Тоді м’яч буде позиціонований щодо поля:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Тоді м’яч буде позиціонований щодо поля:
Тоді м’яч буде позиціонований відносно поля:


```css
#field {
Expand All @@ -16,36 +16,36 @@ Then the ball will be positioned relatively to the field:

#ball {
position: absolute;
left: 0; /* relative to the closest positioned ancestor (field) */
left: 0; /* по відношенню до найближчого розташованого предка (field) */
top: 0;
transition: 1s all; /* CSS animation for left/top makes the ball fly */
transition: 1s all; /* CSS-анімація для значень left/top робить пересування м’яча плавним */
}
```

Next we need to assign the correct `ball.style.left/top`. They contain field-relative coordinates now.
Далі ми маємо призначити коректні значення `ball.style.left/top`. Зараз вони містять координати щодо поля.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Далі ми маємо призначити коректні значення `ball.style.left/top`. Зараз вони містять координати щодо поля.
Далі ми маємо призначити коректні значення `ball.style.left/top`. Зараз вони містять координати відносно поля.

Здається, що так краще, як вважаєте?


Here's the picture:
Як на зображенні:

![](move-ball-coords.svg)

We have `event.clientX/clientY` -- window-relative coordinates of the click.
Ми маємо `event.clientX/clientY` -- координати натискання мишки щодо вікна браузера.

To get field-relative `left` coordinate of the click, we can substract the field left edge and the border width:
Щоб отримати значення `left` для м’яча після натискання мишки щодо поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Щоб отримати значення `left` для м’яча після натискання мишки щодо поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі:
Щоб отримати значення `left` для м’яча після натискання мишки відносно поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі:


```js
let left = event.clientX - fieldCoords.left - field.clientLeft;
```

Normally, `ball.style.left` means the "left edge of the element" (the ball). So if we assign that `left`, then the ball edge, not center, would be under the mouse cursor.
Значення `ball.style.left` означає «лівий край елемента» (м’яча). І якщо ми призначимо такий `left` для м’яча, то його ліва межа, а не центр, буде під курсором миші.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Значення `ball.style.left` означає «лівий край елемента» (м’яча). І якщо ми призначимо такий `left` для м’яча, то його ліва межа, а не центр, буде під курсором миші.
Значення `ball.style.left` означає "лівий край елемента" (м’яча). І якщо ми призначимо такий `left` для м’яча, то його ліва межа, а не центр, буде під курсором миші.


We need to move the ball half-width left and half-height up to make it center.
Нам потрібно зрушити м'яч на половину його висоти вгору та половину його ширини вліво, щоб центр м’яча точно збігався з точкою натискання мишки.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Нам потрібно зрушити м'яч на половину його висоти вгору та половину його ширини вліво, щоб центр м’яча точно збігався з точкою натискання мишки.
Нам потрібно зрушити мяч на половину його висоти вгору та половину його ширини вліво, щоб центр м’яча точно збігався з точкою натискання мишки.


So the final `left` would be:
У результаті значення для `left` буде таким:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
У результаті значення для `left` буде таким:
В результаті значення для `left` буде таким:


```js
let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidth/2;
```

The vertical coordinate is calculated using the same logic.
Вертикальна координата обчислюватиметься за тією ж логікою.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Вертикальна координата обчислюватиметься за тією ж логікою.
Вертикальна координата обчислюється за тією ж логікою.


Please note that the ball width/height must be known at the time we access `ball.offsetWidth`. Should be specified in HTML or CSS.
Слід пам’ятати, що ширина та висота м’яча має бути відома в той момент, коли ми отримуємо значення `ball.offsetWidth`. Це значення може бути задано в HTML або CSS.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

<body style="height:2000px">

Click on a field to move the ball there.
Натисніть поле, щоб перемістити м’яч.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Натисніть поле, щоб перемістити м’яч.
Клікнить по полю, щоб перемістити м’яч.

<br>


Expand All @@ -39,29 +39,29 @@
<script>
field.onclick = function(event) {

// window-relative field coordinates
// координати поля щодо вікна браузера
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// координати поля щодо вікна браузера
// координати поля відносно вікна браузера

let fieldCoords = this.getBoundingClientRect();

// the ball has position:absolute, the field: position:relative
// so ball coordinates are relative to the field inner left-upper corner
// м’яч має абсолютне позиціювання (position:absolute), поле -- відносне (position:relative)
// таким чином, координати м’яча розраховуються відносно внутрішнього, верхнього лівого кута поля.
let ballCoords = {
top: event.clientY - fieldCoords.top - field.clientTop - ball.clientHeight / 2,
left: event.clientX - fieldCoords.left - field.clientLeft - ball.clientWidth / 2
};

// prevent crossing the top field boundary
// забороняємо перетинати верхню межу поля
if (ballCoords.top < 0) ballCoords.top = 0;

// prevent crossing the left field boundary
// забороняємо перетинати ліву межу поля
if (ballCoords.left < 0) ballCoords.left = 0;


// // prevent crossing the right field boundary
// забороняємо перетинати праву межу поля
if (ballCoords.left + ball.clientWidth > field.clientWidth) {
ballCoords.left = field.clientWidth - ball.clientWidth;
}

// prevent crossing the bottom field boundary
// забороняємо перетинати нижню межу поля
if (ballCoords.top + ball.clientHeight > field.clientHeight) {
ballCoords.top = field.clientHeight - ball.clientHeight;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

<body style="height:2000px">

Click on a field to move the ball there.
<br> The ball should never leave the field.
Натисніть поле, щоб перемістити м’яч.
<br> М’яч ніколи не повинен покидати поля.


<div id="field">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ importance: 5

---

# Move the ball across the field
# Пересуньте м’яч по полю

Move the ball across the field to a click. Like this:
Нехай м’яч переміщається при натисканні на поле, туди, де був клік, ось так:

[iframe src="solution" height="260" link]

Requirements:
Вимоги:

- The ball center should come exactly under the pointer on click (if possible without crossing the field edge).
- CSS-animation is welcome.
- The ball must not cross field boundaries.
- When the page is scrolled, nothing should break.
- Центр м’яча повинен збігатися з курсором миші (якщо це можливо без перетину країв поля);
- CSS-анімація бажана, але не є обов’язковою;
- М’яч у жодному разі не повинен перетинати межі поля;
- При прокручуванні сторінки нічого не повинно ламатися;

Notes:
Нотатки:

- The code should also work with different ball and field sizes, not be bound to any fixed values.
- Use properties `event.clientX/event.clientY` for click coordinates.
- Код повинен уміти працювати з різними розмірами м’яча та поля, не прив’язуватися до будь-яких фіксованих значень.
- Використовуйте властивості `event.clientX/event.clientY`, щоб вирахувати координати миші при кліці.
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@

# HTML/CSS
First let's create HTML/CSS.
Для початку створимо розмітку HTML/CSS нашого меню.

A menu is a standalone graphical component on the page, so it's better to put it into a single DOM element.
Меню -- це окремий графічний компонент на сторінці, тому його краще винести в окремий DOM-елемент.

A list of menu items can be laid out as a list `ul/li`.
Список пунктів меню може бути представлений у вигляді списку `ul/li`.

Here's the example structure:
Приклад HTML структури:

```html
<div class="menu">
<span class="title">Sweeties (click me)!</span>
<span class="title">Солодощі (тисни на мене)!</span>
<ul>
<li>Cake</li>
<li>Donut</li>
<li>Honey</li>
<li>Тістечко</li>
<li>Пончик</li>
<li>Мед</li>
</ul>
</div>
```

We use `<span>` for the title, because `<div>` has an implicit `display:block` on it, and it will occupy 100% of the horizontal width.
Для заголовка ми використовуємо тег `<span>`, тому що `<div>`, як і будь-який блоковий елемент, має приховану властивість `display:block`, це означає, що він має 100% ширину.

Like this:
Наприклад:

```html autorun height=50
<div style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</div>
<div style="border: solid red 1px" onclick="alert(1)">Солодощі (тисни мене)!</div>
```

So if we set `onclick` on it, then it will catch clicks to the right of the text.
Таким чином, якщо ми додамо обробник події в `onclick`, то він буде спрацьовувати на клік на всій ширині меню.

As `<span>` has an implicit `display: inline`, it occupies exactly enough place to fit all the text:
Оскільки `<span>` має неявну властивість `display: inline`, він займає тільки стільки місця, щоб умістити весь текст:

```html autorun height=50
<span style="border: solid red 1px" onclick="alert(1)">Sweeties (click me)!</span>
<span style="border: solid red 1px" onclick="alert(1)">Солодощі (тисни мене)!</span>
```

# Toggling the menu
# Перемикання меню

Toggling the menu should change the arrow and show/hide the menu list.
Функціонал перемикання меню повиннен змінювати стрілку та приховувати або показувати список елементів меню.

All these changes are perfectly handled by CSS. In JavaScript we should label the current state of the menu by adding/removing the class `.open`.
Всі ці зміни можна реалізувати засобами CSS. За допомогою JavaScript ми будемо змінювати вигляд меню, додаючи або видаляючи клас `.open`.

Without it, the menu will be closed:
Без класу `.open` меню буде закритим:

```css
.menu ul {
Expand All @@ -58,7 +58,7 @@ Without it, the menu will be closed:
}
```

...And with `.open` the arrow changes and the list shows up:
...А з класом `.open` стрілка зміниться і список буде показано:

```css
.menu.open .title::before {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
<body>

<div id="sweeties" class="menu">
<span class="title">Sweeties (click me)!</span>
<span class="title">Солодощі (тисни на мене)!</span>
<ul>
<li>Cake</li>
<li>Donut</li>
<li>Honey</li>
<li>Тістечко</li>
<li>Пончик</li>
<li>Мед</li>
</ul>

</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
</head>
<body>

▶ ▼ Sweeties (click me)!
▶ ▼ Солодощі (тисни на мене)!
<ul>
<li>Cake</li>
<li>Donut</li>
<li>Honey</li>
<li>Тістечко</li>
<li>Пончик</li>
<li>Мед</li>
</ul>

</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ importance: 5

---

# Create a sliding menu
# Створіть меню, що розкривається

Create a menu that opens/collapses on click:
Створіть меню, яке відкривається/згортається після кліку:

[iframe border=1 height=100 src="solution"]

P.S. HTML/CSS of the source document is to be modified.
P.S. HTML/CSS вихідного документа можна і треба змінювати.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

To add the button we can use either `position:absolute` (and make the pane `position:relative`) or `float:right`. The `float:right` has the benefit that the button never overlaps the text, but `position:absolute` gives more freedom. So the choice is yours.
Щоб додати кнопку закриття, ми можемо використовувати або `position:absolute` (і зробити плитку (pane) `position:relative`) або `float:right`. Перевага варіанта з `float:right` у тому, що кнопка закриття ніколи не перекриє текст, але варіант `position:absolute` дає більше свободи для дій. Загалом вибір за вами.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Щоб додати кнопку закриття, ми можемо використовувати або `position:absolute` (і зробити плитку (pane) `position:relative`) або `float:right`. Перевага варіанта з `float:right` у тому, що кнопка закриття ніколи не перекриє текст, але варіант `position:absolute` дає більше свободи для дій. Загалом вибір за вами.
Щоб додати кнопку закриття, ми можемо використовувати або `position:absolute` (і зробити повідомлення(pane) `position:relative`) або `float:right`. Перевага варіанта з `float:right` у тому, що кнопка закриття ніколи не перекриє текст, але варіант `position:absolute` дає більше свободи для дій. Загалом вибір за вами.


Then for each pane the code can be like:
Тоді для кожного повідомлення(pane) код може бути таким:
```js
pane.insertAdjacentHTML("afterbegin", '<button class="remove-button">[x]</button>');
```

Then the `<button>` becomes `pane.firstChild`, so we can add a handler to it like this:
Елемент `<button>` стає `pane.firstChild`, таким чином ми можемо додати до нього обробник події:

```js
pane.firstChild.onclick = () => pane.remove();
Expand Down
Loading