Skip to content

Commit 8a8d92e

Browse files
authored
Merge pull request #322 from AntonBurchak/drag-n-drop
Drag'n'Drop with mouse events
2 parents 81bb2e8 + b90a49a commit 8a8d92e

File tree

17 files changed

+178
-178
lines changed

17 files changed

+178
-178
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
As we can see from HTML/CSS, the slider is a `<div>` with a colored background, that contains a runner -- another `<div>` with `position:relative`.
1+
Як можна бачити з `HTML/CSS`, слайдер -- це `<div>`, з кольровим фоном, всередині якого знаходиться інший `<div>`, оформлений як бігунок, з `position: relative`.
22

3-
To position the runner we use `position:relative`, to provide the coordinates relative to its parent, here it's more convenient here than `position:absolute`.
3+
Використаємо для його позиціювання `position: relative`, тобто координати встановлюються не абсолютні (`position: absolute`), а відносно батьківського елементу, бо це зручніше.
44

5-
Then we implement horizontal-only Drag'n'Drop with limitation by width.
5+
І далі реалізуємо Drag'n'Drop тільки по горизонталі, з обмеженням по ширині.

2-ui/3-event-details/4-mouse-drag-and-drop/1-slider/solution.view/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616
let thumb = slider.querySelector('.thumb');
1717

1818
thumb.onmousedown = function(event) {
19-
event.preventDefault(); // prevent selection start (browser action)
19+
event.preventDefault(); // запобігає запуску виділення (типова дія браузера)
2020

2121
let shiftX = event.clientX - thumb.getBoundingClientRect().left;
22-
// shiftY not needed, the thumb moves only horizontally
22+
// shiftY не потрібен, слайдер рухається тільки по горизонталі
2323

2424
document.addEventListener('mousemove', onMouseMove);
2525
document.addEventListener('mouseup', onMouseUp);
2626

2727
function onMouseMove(event) {
2828
let newLeft = event.clientX - shiftX - slider.getBoundingClientRect().left;
2929

30-
// the pointer is out of slider => lock the thumb within the bounaries
30+
// курсор вийшов за межі слайдера => зафіксуємо бігунок в межах слайдера.
3131
if (newLeft < 0) {
3232
newLeft = 0;
3333
}

2-ui/3-event-details/4-mouse-drag-and-drop/1-slider/source.view/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</div>
1414

1515
<script>
16-
// ...your code...
16+
// ...ваш код...
1717
</script>
1818

1919
</body>

2-ui/3-event-details/4-mouse-drag-and-drop/1-slider/task.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ importance: 5
22

33
---
44

5-
# Slider
5+
# Слайдер
66

7-
Create a slider:
7+
Створіть слайдер:
88

99
[iframe src="solution" height=60 border=1]
1010

11-
Drag the blue thumb with the mouse and move it.
11+
Наведіть курсор миші на бігунок слайдеру, затисніть кнопку миші і рухайте бігунок переміщаючи курсор.
1212

13-
Important details:
13+
Важливі деталі:
1414

15-
- When the mouse button is pressed, during the dragging the mouse may go over or below the slider. The slider will still work (convenient for the user).
16-
- If the mouse moves very fast to the left or to the right, the thumb should stop exactly at the edge.
15+
- При натиснутій кнопці миші, курсор може виходити за межі слайдера, але слайдер все одно має працювати (це зручно для користувача).
16+
- Слайдер повинен нормально працювати при різкому русі миші ливоруч або праворуч за межі слайдера. При цьому бігунок повинен зупинятися чітко біля його краю.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
To drag the element we can use `position:fixed`, it makes coordinates easier to manage. At the end we should switch it back to `position:absolute` to lay the element into the document.
1+
Щоб перетягнути елемент, ми можемо використовувати `position: fixed`, це робить управління координатами простішим. Після завершення слід переключитися назад на `position: absolute`, щоб елемент залишився частиною сторінки.
22

3-
When coordinates are at window top/bottom, we use `window.scrollTo` to scroll it.
3+
Коли координати знаходяться у верхній/нижній частині вікна, ми використовуємо `window.scrollTo` для прокрутки.
44

5-
More details in the code, in comments.
5+
Деталі рішення розписані в коментарях у коді.

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/index.html

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88

99
<body>
1010

11-
<h2>Place superheroes around the soccer field.</h2>
12-
13-
<p>Superheroes and the ball are elements with the class "draggable". Make them really draggable.</p>
14-
15-
<p>Important: limit dragging by the window. If a draggable reaches window top or bottom, then the page should scroll to let us drag it further.</p>
16-
17-
<p>If your screen is big enough to fit the whole document -- make the window smaller to get vertical scrolling, so that you could test it.</p>
18-
19-
<p>In this task it's enough to handle vertical scrolling. There's no horizontal scrolling usually, and it's handled the similar way if needed.</p>
20-
21-
<p>And one more thing: heroes may never leave the page. If they reach the edge of the document, no dragging outside of it.</p>
22-
11+
<h2>Розставте супергероїв полем.</h2>
12+
13+
<p>Супергерої і м’яч -- це елементи з класом "draggable". Зробіть так, щоб їх можна було переносити.</p>
14+
15+
<p>Важливо: обмежити перетягування межами вікна. Якщо супергероя підносять до верхньої або нижньої межі вікна, сторінка повинна автоматично прокручуватися.</p>
16+
17+
<p>Якщо сторінка міститься на екрані повністю і не має вертикальної прокрутки -- зробіть вікно браузера менше, щоб протестувати цю можливість.</p>
18+
19+
<p>У цьому завданні достатньо впоратися з вертикальною прокруткою. Зазвичай горизонтальна прокрутка відсутня, вона обробляється аналогічно, якщо це необхідно.</p>
20+
21+
<p>Так, і ще: супергерої ні за яких умов не повинні потрапити за край екрану.</p>
22+
2323
<div id="field">
2424

2525
</div>

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ html, body {
1010
float: left;
1111
}
1212

13-
/* heroes and the ball (dragables) */
13+
/* герої і м’яч (dragables) */
1414

1515
.hero {
1616
background: url(https://js.cx/drag-heroes/heroes.png);

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ document.addEventListener('mousedown', function(event) {
2424
moveAt(event.clientX, event.clientY);
2525
}
2626

27-
// on drag start:
28-
// remember the initial shift
29-
// move the element position:fixed and a direct child of body
27+
// на початку переміщення елемента:
28+
// зберегаємо місце кліку по елементу
29+
// перемикаємо позиціонування елемента (position: fixed) і рухаємо елемент
3030
function startDrag(element, clientX, clientY) {
3131
if(isDragging) {
3232
return;
@@ -45,7 +45,7 @@ document.addEventListener('mousedown', function(event) {
4545
moveAt(clientX, clientY);
4646
};
4747

48-
// switch to absolute coordinates at the end, to fix the element in the document
48+
// перемикаємося назад на абсолютні координати щоб закріпити елемент відносно документа
4949
function finishDrag() {
5050
if(!isDragging) {
5151
return;
@@ -61,49 +61,49 @@ document.addEventListener('mousedown', function(event) {
6161
}
6262

6363
function moveAt(clientX, clientY) {
64-
// new window-relative coordinates
64+
// обчислюємо нові координати (відносно вікна)
6565
let newX = clientX - shiftX;
6666
let newY = clientY - shiftY;
6767

68-
// check if the new coordinates are below the bottom window edge
69-
let newBottom = newY + dragElement.offsetHeight; // new bottom
68+
// перевіряємо, чи не виходять нові координати за нижній край вікна:
69+
let newBottom = newY + dragElement.offsetHeight; // нові координати
7070

71-
// below the window? let's scroll the page
71+
// виходять за межі вікна? прокручуємо сторінку
7272
if (newBottom > document.documentElement.clientHeight) {
73-
// window-relative coordinate of document end
73+
// координата нижнього краю документа щодо вікна
7474
let docBottom = document.documentElement.getBoundingClientRect().bottom;
7575

76-
// scroll the document down by 10px has a problem
77-
// it can scroll beyond the end of the document
78-
// Math.min(how much left to the end, 10)
76+
// прокрутка документа на 10px вниз має проблему --
77+
// він може прокрутити документ за його межі,
78+
// тому використовуємо Math.min (відстань до кінця, 10)
7979
let scrollY = Math.min(docBottom - newBottom, 10);
8080

81-
// calculations are imprecise, there may be rounding errors that lead to scrolling up
82-
// that should be impossible, fix that here
81+
// обчислення можуть бути не зовсім точні -- трапляються помилки при округленні,
82+
// які призводять до негативного значенням прокрутки. Відфільтруємо їх:
8383
if (scrollY < 0) scrollY = 0;
8484

8585
window.scrollBy(0, scrollY);
8686

87-
// a swift mouse move make put the cursor beyond the document end
88-
// if that happens -
89-
// limit the new Y by the maximally possible (right at the bottom of the document)
87+
// швидке переміщення миші може помістити курсор за межі документа вниз
88+
// якщо це сталося -
89+
// обмежуємо нове значення Y максимально можливим, виходячи з розміру документа:
9090
newY = Math.min(newY, document.documentElement.clientHeight - dragElement.offsetHeight);
9191
}
9292

93-
// check if the new coordinates are above the top window edge (similar logic)
93+
// перевіряємо, чи не переходять нові координати за верхній край вікна (за схожим алгоритмом)
9494
if (newY < 0) {
9595
// scroll up
9696
let scrollY = Math.min(-newY, 10);
97-
if (scrollY < 0) scrollY = 0; // check precision errors
97+
if (scrollY < 0) scrollY = 0; // перевіряємо помилки точності
9898

9999
window.scrollBy(0, -scrollY);
100-
// a swift mouse move can put the cursor beyond the document start
101-
newY = Math.max(newY, 0); // newY may not be below 0
100+
// швидке переміщення миші може помістити курсор за межі документа зверху
101+
newY = Math.max(newY, 0); // newY не може бути менше нуля
102102
}
103103

104104

105-
// limit the new X within the window boundaries
106-
// there's no scroll here so it's simple
105+
// обмежимо newX розмірами вікна
106+
// згідно з умовою, горизонтальна прокрутка відсутня, тому це не складно:
107107
if (newX < 0) newX = 0;
108108
if (newX > document.documentElement.clientWidth - dragElement.offsetWidth) {
109109
newX = document.documentElement.clientWidth - dragElement.offsetWidth;

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/source.view/index.html

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88

99
<body>
1010

11-
<h2>Place superheroes around the soccer field.</h2>
12-
13-
<p>Superheroes and the ball are elements with the class "draggable". Make them really draggable.</p>
14-
15-
<p>Important: limit dragging by the window. If a draggable reaches window top or bottom, then the page should scroll to let us drag it further.</p>
16-
17-
<p>If your screen is big enough to fit the whole document -- make the window smaller to get vertical scrolling, so that you could test it.</p>
18-
19-
<p>In this task it's enough to handle vertical scrolling. There's no horizontal scrolling usually, and it's handled the similar way if needed.</p>
20-
21-
<p>And one more thing: heroes may never leave the page. If they reach the edge of the document, no dragging outside of it.</p>
22-
11+
<h2>Розставте супергероїв полем.</h2>
12+
13+
<p>Супергерої і м’яч - це елементи з класом "draggable". Зробіть так, щоб їх можна було переносити.</p>
14+
15+
<p>Важливо: обмежити перетягування межами вікна. Якщо супергероя підносять до верхньої або нижньої межі сторінки, вона повинна автоматично прокручуватися.</p>
16+
17+
<p>Якщо сторінка поміщається на вашому екрані цілком і не має вертикальної прокрутки - зробіть вікно браузера менше, щоб протестувати цю можливість.</p>
18+
19+
<p>У цьому завданні достатньо впоратися з вертикальною прокруткою. Зазвичай немає горизонтальної прокрутки, і вона обробляється аналогічним чином, якщо це необхідно.</p>
20+
21+
<p>Так, і ще: супергерої ні за яких умов не повинні потрапити за край екрану.</p>
22+
2323
<div id="field">
2424

2525
</div>

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/source.view/soccer.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ html, body {
1010
float: left;
1111
}
1212

13-
/* heroes and the ball (dragables) */
13+
/* герої і м’яч (dragables) */
1414

1515
.hero {
1616
background: url(https://js.cx/drag-heroes/heroes.png);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
// Your code
1+
// Ваш код

2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/task.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ importance: 5
22

33
---
44

5-
# Drag superheroes around the field
5+
# Розставте супергероїв полем
66

7-
This task can help you to check understanding of several aspects of Drag'n'Drop and DOM.
7+
У цьому завданні ви можете перевірити своє розуміння відразу декількох аспектів Drag'n'Drop і DOM.
88

9-
Make all elements with class `draggable` -- draggable. Like a ball in the chapter.
9+
Зробіть так, щоб елементи з класом `draggable` -- можна було переносити мишкою. Як м’яч в цьому розділі.
1010

11-
Requirements:
11+
Вимоги до реалізації:
1212

13-
- Use event delegation to track drag start: a single event handler on `document` for `mousedown`.
14-
- If elements are dragged to top/bottom window edges -- the page scrolls up/down to allow further dragging.
15-
- There is no horizontal scroll (this makes the task a bit simpler, adding it is easy).
16-
- Draggable elements or their parts should never leave the window, even after swift mouse moves.
13+
- Використовуйте делегування подій для відстеження початку перетягування: тільки один обробник подій `mousedown` на `document`.
14+
- Якщо елементи підносять до верхньої/нижньої межі вікна -- вікно повинне прокручуватися вгору/вниз, щоб дозволити подальше перетягування.
15+
- Горизонтальна прокрутка відсутня (трохи спрощує завдання, її просто додати).
16+
- Елемент при перенесенні, навіть при різких рухах мишкою, не повинен навіть частково потрапити поза вікно.
1717

18-
The demo is too big to fit it here, so here's the link.
18+
Демо занадто велике для розміщення тут, перейдіть за посиланням нижче.
1919

2020
[demo src="solution"]

0 commit comments

Comments
 (0)