Moving the mouse by dolgachio · Pull Request #620 · javascript-tutorial/uk.javascript.info · GitHub
Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<style>
body {
height: 2000px;
/* the tooltip should work after page scroll too */
/* спливаюча підказка також має працювати після прокручування сторінки */
}

.tooltip {
Expand Down Expand Up @@ -49,21 +49,21 @@
<body>


<div data-tooltip="Here is the house interior" id="house">
<div data-tooltip="Here is the roof" id="roof"></div>
<div data-tooltip="Ось – інтер’єр будинку" id="house">
<div data-tooltip="Ось – дах" id="roof"></div>

<p>Once upon a time there was a mother pig who had three little pigs.</p>
<p>Жила-була мама-свиня, у якої було троє поросят.</p>

<p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."</p>
<p>Троє поросят виросли такі великі, що їхня мати сказала їм: "Ви занадто великі, щоб жити тут далі. Ви повинні йти і будувати собі будинки. Але бережіть себе, щоб вовк вас не спіймав."</p>

<p>The three little pigs set off. "We will take care that the wolf does not catch us," they said.</p>
<p>Троє поросят рушили. "Будемо берегти один одного, щоб вовк нас не спіймав", - сказали вони.</p>

<p>Soon they met a man. <a href="https://en.wikipedia.org/wiki/The_Three_Little_Pigs" data-tooltip="Read on…">Hover over me</a></p>
<p>Незабаром вони зустріли чоловіка.<a href="https://uk.wikipedia.org/wiki/Троє_поросят" data-tooltip="Читайте далі…">Наведіть на мене мишу</a></p>

</div>

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

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

---

# Improved tooltip behavior
# Покращена поведінка спливаючої підказки

Write JavaScript that shows a tooltip over an element with the attribute `data-tooltip`. The value of this attribute should become the tooltip text.
Напишіть JavaScript, який покаже спливаючу підказку над елементом із атрибутом `data-tooltip`. Значення цього атрибута має стати текстом підказки.

That's like the task <info:task/behavior-tooltip>, but here the annotated elements can be nested. The most deeply nested tooltip is shown.
Це як задача <info:task/behavior-tooltip>, але тут елементи можуть бути вкладеними. Ви маєте показати найбільш глибоко вкладену підказку.

Only one tooltip may show up at the same time.
Одночасно може відображатися лише одна підказка.

For instance:
Наприклад:

```html
<div data-tooltip="Hereis the house interior" id="house">
<div data-tooltip="Hereis the roof" id="roof"></div>
<div data-tooltip="Осьінтер’єр будинку" id="house">
<div data-tooltip="Осьдах" id="roof"></div>
...
<a href="https://en.wikipedia.org/wiki/The_Three_Little_Pigs" data-tooltip="Read on…">Hover over me</a>
<a href="https://uk.wikipedia.org/wiki/Троє_поросят" data-tooltip="Читайте далі…">Наведіть на мене вказівник</a>
</div>
```

The result in iframe:
Результат в iframe:

[iframe src="solution" height=300 border=1]
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@

The algorithm looks simple:
1. Put `onmouseover/out` handlers on the element. Also can use `onmouseenter/leave` here, but they are less universal, won't work if we introduce delegation.
2. When a mouse cursor entered the element, start measuring the speed on `mousemove`.
3. If the speed is slow, then run `over`.
4. When we're going out of the element, and `over` was executed, run `out`.
Алгоритм виглядає просто:
1. Додайте обробники `onmouseover/out` на елемент. Тут також можна використовувати `onmouseenter/leave`, але вони менш універсальні, і не працюватимуть, якщо ми використаємо делегування подій.
2. Коли вказівник миші увійшов на елемент, почніть вимірювати швидкість на `mousemove`.
3. Якщо швидкість низька, то запускаємо `over`.
4. Коли вказівник виходить за межі елемента, і `over` закінчила свою роботу, запускаємо `out`.

But how to measure the speed?
Але як виміряти швидкість?

The first idea can be: run a function every `100ms` and measure the distance between previous and new coordinates. If it's small, then the speed is small.
Перша ідея може бути такою: запускати функцію кожні `100ms` і вимірювати відстань між попередньою та новою координатами. Якщо відстань маленька, то швидкість невелика.

Unfortunately, there's no way to get "current mouse coordinates" in JavaScript. There's no function like `getCurrentMouseCoordinates()`.
На жаль, у JavaScript немає способу отримати поточні координати вказівника миші. Немає таких функцій, як `getCurrentMouseCoordinates()`.

The only way to get coordinates is to listen for mouse events, like `mousemove`, and take coordinates from the event object.
Єдиний спосіб отримати координати -- в обробнику подій миші, наприклад `mousemove`, і брати координати з об’єкта події.

So let's set a handler on `mousemove` to track coordinates and remember them. And then compare them, once per `100ms`.
Отже, давайте додамо обробник на `mousemove`, де відстежемо і запам'ятаємо поточні координати. А далі будемо порівнювати їх раз на `100ms`.

P.S. Please note: the solution tests use `dispatchEvent` to see if the tooltip works right.
P.S. Зверніть увагу: тести рішення використовують `dispatchEvent`, щоб перевірити, чи підказка працює правильно.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
class HoverIntent {

constructor({
sensitivity = 0.1, // speed less than 0.1px/ms means "hovering over an element"
interval = 100, // measure mouse speed once per 100ms
sensitivity = 0.1, // швидкість менше 0,1 пікселів/мс означає "наведення вказівника на елемент"
interval = 100, // вимірювати швидкість миші раз на 100ms: обчислити відстань між попередньою та наступною точками
elem,
over,
out
Expand All @@ -15,12 +15,12 @@ class HoverIntent {
this.over = over;
this.out = out;

// make sure "this" is the object in event handlers.
// переконайтеся, що "this" є нашми об’єктом в обробниках подій.
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseOut = this.onMouseOut.bind(this);

// and in time-measuring function (called from setInterval)
// і у функції вимірювання часу (викликається з setInterval)
this.trackSpeed = this.trackSpeed.bind(this);

elem.addEventListener("mouseover", this.onMouseOver);
Expand All @@ -32,16 +32,16 @@ class HoverIntent {
onMouseOver(event) {

if (this.isOverElement) {
// if we're over the element, then ignore the event
// we are already measuring the speed
// якщо ми знову пройшли над елементом, ігноруємо подію,
// бо ми вже вимірюємо швидкість
return;
}

this.isOverElement = true;

// after every mousemove we'll be check the distance
// between the previous and the current mouse coordinates
// if it's less than sensivity, then the speed is slow
// після кожного руху миші ми будемо перевіряти відстань
// між попередньою та поточною координатами миші
// якщо ця відстань менше ніж значення sensitivity, швидкість повільна

this.prevX = event.pageX;
this.prevY = event.pageY;
Expand All @@ -52,13 +52,13 @@ class HoverIntent {
}

onMouseOut(event) {
// if left the element
// якщо залишили елемент
if (!event.relatedTarget || !elem.contains(event.relatedTarget)) {
this.isOverElement = false;
this.elem.removeEventListener('mousemove', this.onMouseMove);
clearInterval(this.checkSpeedInterval);
if (this.isHover) {
// if there was a stop over the element
// якщо була зупинка над елементом
this.out.call(this.elem, event);
this.isHover = false;
}
Expand All @@ -76,7 +76,7 @@ class HoverIntent {
let speed;

if (!this.lastTime || this.lastTime == this.prevTime) {
// cursor didn't move
// вказівник не рухався
speed = 0;
} else {
speed = Math.sqrt(
Expand All @@ -90,7 +90,7 @@ class HoverIntent {
this.isHover = true;
this.over.call(this.elem);
} else {
// speed fast, remember new coordinates as the previous ones
// якщо рухається швидко, записуємо нові координати як попередні
this.prevX = this.lastX;
this.prevY = this.lastY;
this.prevTime = this.lastTime;
Expand Down
Loading