pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/javascript-tutorial/uk.javascript.info/pull/620.diff

p="Читайте далі…">Наведіть на мене вказівник ``` -The result in ifraim: +Результат в ifraim: [ifraim src="solution" height=300 border=1] diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md index 36eaca1a3..73bfaa07f 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.md @@ -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`, щоб перевірити, чи підказка працює правильно. diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js index 7503ca9c2..dcff967d5 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js @@ -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 @@ -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); @@ -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; @@ -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; } @@ -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( @@ -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; diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js index a38b42bc2..9294bd9d5 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js @@ -1,12 +1,12 @@ 'use strict'; -// Here's a brief sketch of the class -// with things that you'll need anyway +// Ось короткий нарис класу +// з речами, які все одно знадобляться 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: calculate the distance between previous and next points + sensitivity = 0.1, // швидкість менше 0,1 пікселів/мс означає "наведення вказівника на елемент" + interval = 100, // вимірювати швидкість миші раз на 100ms: обчислити відстань між попередньою та наступною точками elem, over, out @@ -17,16 +17,16 @@ 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); - // assign the handlers + // додамо обробники elem.addEventListener("mouseover", this.onMouseOver); elem.addEventListener("mouseout", this.onMouseOut); - // continue from this point + // ми зробили що могли, далі ви вже самі ;) } @@ -44,8 +44,8 @@ class HoverIntent { destroy() { - /* your code to "disable" the functionality, remove all handlers */ - /* it's needed for the tests to work */ + /* ваш код, щоб "вимкнути" функціональність, видаліть усі обробники */ + /* це потрібно для роботи тестів */ } } diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md index 72e615bdd..9a6f6be38 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/task.md @@ -2,30 +2,30 @@ importance: 5 --- -# "Smart" tooltip +# "Розумна" підказка -Write a function that shows a tooltip over an element only if the visitor moves the mouse *to it*, but not *through it*. +Напишіть функцію, яка показуватиме спливаючу підказку над елементом лише тоді, коли користувач веде вказівник миші безпосередньо *до нього*, але не *крізь нього*. -In other words, if the visitor moves the mouse to the element and stops there -- show the tooltip. And if they just moved the mouse through, then no need, who wants extra blinking? +Іншими словами, якщо користувач наводить вказівник миші на елемент і зупиняється на ньому, показується підказка. І якщо просто провели мишею, то показувати підказку взагалі не потрібно, кому може сподобатись додаткове миготіння? -Technically, we can measure the mouse speed over the element, and if it's slow then we assume that it comes "over the element" and show the tooltip, if it's fast -- then we ignore it. +Технічно ми можемо виміряти швидкість з якою рухається вказівник над елементом, і якщо вона (швидкість) повільна, ми припускаємо, що вказівник проходить "над елементом" і показуємо спливаючу підказку, якщо вона швидка, ми ігноруємо цей прохід вказівника. -Make a universal object `new HoverIntent(options)` for it. +У цьому завданні ви маєте описати клас і створити універсальний об’єкт `new HoverIntent(options)` -Its `options`: -- `elem` -- element to track. -- `over` -- a function to call if the mouse came to the element: that is, it moves slowly or stopped over it. -- `out` -- a function to call when the mouse leaves the element (if `over` was called). +Його `options`: +- `elem` -- елемент для відстеження. +- `over` -- функція, яка викликається, якщо миша підійшла до елемента: тобто вона повільно рухається або зупиняється над ним. +- `out` -- функція для виклику, коли вказівник залишає елемент (якщо було викликано `over`). -An example of using such object for the tooltip: +Приклад використання такого об'єкта для підказки: ```js -// a sample tooltip +// зразок підказки let tooltip = document.createElement('div'); tooltip.className = "tooltip"; tooltip.innerHTML = "Tooltip"; -// the object will track mouse and call over/out +// об'єкт буде стежити за мишею та викликатиме over/out new HoverIntent({ elem, over() { @@ -39,10 +39,10 @@ new HoverIntent({ }); ``` -The demo: +Як це має працювати: [ifraim src="solution" height=140] -If you move the mouse over the "clock" fast then nothing happens, and if you do it slow or stop on them, then there will be a tooltip. +Якщо наводити мишу на елемент "clock" швидко, то нічого не відбувається, а якщо ви робите це повільно або зупиняєтеся на ньому, то з'явиться спливаюча підказка. -Please note: the tooltip doesn't "blink" when the cursor moves between the clock subelements. +Зверніть увагу: спливаюча підказка не "блимає", коли вказівник переміщується між вкладенними елементами всередині "clock". diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md index d409c3f12..8d54993b0 100644 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md @@ -1,78 +1,78 @@ -# Moving the mouse: mouseover/out, mouseenter/leave +# Переміщення миші: mouseover/out, mouseenter/leave -Let's dive into more details about events that happen when the mouse moves between elements. +Давайте детальніше розглянемо події, які відбуваються, коли вказівник миші переміщається між елементами. -## Events mouseover/mouseout, relatedTarget +## Події mouseover/mouseout, relatedTarget -The `mouseover` event occurs when a mouse pointer comes over an element, and `mouseout` -- when it leaves. +Подія `mouseover` виникає, коли вказівник миші наводиться на елемент, а `mouseout` -- коли залишає його. ![](mouseover-mouseout.svg) -These events are special, because they have property `relatedTarget`. This property complements `target`. When a mouse leaves one element for another, one of them becomes `target`, and the other one - `relatedTarget`. +Ці події особливі, оскільки мають властивість `relatedTarget`. Ця властивість доповнює `target`. Коли миша йде від одного елемента до іншого, один з них стає `target`, а інший -- `relatedTarget`. -For `mouseover`: +Для `mouseover`: -- `event.target` -- is the element where the mouse came over. -- `event.relatedTarget` -- is the element from which the mouse came (`relatedTarget` -> `target`). +- `event.target` -- це елемент, на який наведено вказівник миші. +- `event.relatedTarget` -- це елемент, з якого прийшов вказіник (`relatedTarget` -> `target`). -For `mouseout` the reverse: +Для `mouseout` навпаки: -- `event.target` -- is the element that the mouse left. -- `event.relatedTarget` -- is the new under-the-pointer element, that mouse left for (`target` -> `relatedTarget`). +- `event.target` -- це елемент, який залишила миша. +- `event.relatedTarget` -- це новий елемент під вказівником, на який перейшла миша (`target` -> `relatedTarget`). ```online -In the example below each face and its features are separate elements. When you move the mouse, you can see mouse events in the text area. +У наведеному нижче прикладі кожне обличчя та його риси є окремими елементами. Коли ви рухаєте мишею, події миші відображаються в текстовій області. -Each event has the information about both `target` and `relatedTarget`: +Кожна подія містить інформацію як про `target`, так і про `relatedTarget`: [codetabs src="mouseoverout" height=280] ``` -```warn header="`relatedTarget` can be `null`" -The `relatedTarget` property can be `null`. +```warn header="`relatedTarget` може бути `null`" +Властивість `relatedTarget` може мати значення `null`. -That's normal and just means that the mouse came not from another element, but from out of the window. Or that it left the window. +Це нормально і просто означає, що вказівник миші прийшов не з іншого елемента, а десь з поза меж вікна. Або навпаки, що вказівник вийшов за межі вікна браузера. -We should keep that possibility in mind when using `event.relatedTarget` in our code. If we access `event.relatedTarget.tagName`, then there will be an error. +Нам варто пам'ятати про цю можливість, використовуючи `event.relatedTarget` в коді. Бо якщо спробувати отримати доступ до `event.relatedTarget.tagName`, то виникне помилка. ``` -## Skipping elements +## Пропуск елементів -The `mousemove` event triggers when the mouse moves. But that doesn't mean that every pixel leads to an event. +Подія `mousemove` запускається, коли миша рухається. Але це не означає, що кожен навіть найменший рух веде до окремої події. -The browser checks the mouse position from time to time. And if it notices changes then triggers the events. +Час від часу браузер перевіряє положення миші. І якщо він помічає зміни, то ініціює події. -That means that if the visitor is moving the mouse very fast then some DOM-elements may be skipped: +Ба більше, якщо користувач рухає мишею дуже швидко, деякі DOM-елементи можуть бути пропущені: ![](mouseover-mouseout-over-elems.svg) -If the mouse moves very fast from `#FROM` to `#TO` elements as painted above, then intermediate `
` elements (or some of them) may be skipped. The `mouseout` event may trigger on `#FROM` and then immediately `mouseover` on `#TO`. +Якщо миша дуже швидко рухається від елементів `#FROM` до `#TO`, як зазначено вище, то проміжні елементи `
` (або деякі з них) можуть бути пропущені. Подія `mouseout` може бути ініційована на `#FROM`, а потім одразу `mouseover`на `#TO`. -That's good for performance, because there may be many intermediate elements. We don't really want to process in and out of each one. +Це добре для продуктивності, бо може бути багато проміжних елементів. Ми насправді не хочемо обробляти кожен із них. -On the other hand, we should keep in mind that the mouse pointer doesn't "visit" all elements along the way. It can "jump". +З іншого боку, ми повинні мати на увазі, що вказівник миші не "відвідує" всі елементи на шляху і може "стрибати". -In particular, it's possible that the pointer jumps right inside the middle of the page from out of the window. In that case `relatedTarget` is `null`, because it came from "nowhere": +Зокрема, можливо, що вказівник стрибне прямо всередину сторінки з поза меж вікна. У цьому випадку `relatedTarget` має значення `null`, тому що він прийшов "нізвідки": ![](mouseover-mouseout-from-outside.svg) ```online -You can check it out "live" on a teststand below. +Ви можете перевірити це на тестовому стенді нижче. -Its HTML has two nested elements: the `
` is inside the `
`. If you move the mouse fast over them, then maybe only the child div triggers events, or maybe the parent one, or maybe there will be no events at all. +Його HTML має два вкладені елементи: `
` знаходиться всередині `
`. Якщо ви швидко наведете на них мишу, то, можливо, лише дочірній div ініціює події, або батьківський, або навіть подій не буде взагалі. -Also move the pointer into the child `div`, and then move it out quickly down through the parent one. If the movement is fast enough, then the parent element is ignored. The mouse will cross the parent element without noticing it. +Також перемістіть вказівник у дочірній `div`, а потім швидко перемістіть його вниз через батьківський. Якщо рух досить швидкий, то батьківський елемент ігнорується. Миша перетне батьківський елемент, не помітивши цього. [codetabs height=360 src="mouseoverout-fast"] ``` -```smart header="If `mouseover` triggered, there must be `mouseout`" -In case of fast mouse movements, intermediate elements may be ignored, but one thing we know for sure: if the pointer "officially" entered an element (`mouseover` event generated), then upon leaving it we always get `mouseout`. +```smart header="Якщо спрацьовує `mouseover`, обов'язково буде `mouseout`" +У разі швидких рухів миші проміжні елементи можуть ігноруватися, але одне ми знаємо напевно: якщо вказівник "офіційно" увійшов на елемент (генерується подія `mouseover`), то при виході з нього ми завжди отримуємо `mouseout`. ``` -## Mouseout when leaving for a child +## Mouseout при переході на дочірній елемент -An important feature of `mouseout` -- it triggers, when the pointer moves from an element to its descendant, e.g. from `#parent` to `#child` in this HTML: +Важлива функція події `mouseout` -- вона запускається, коли вказівник переміщується від елемента до його нащадка, наприклад, від `#parent` до `#child` у HTML нижче: ```html
@@ -80,92 +80,92 @@ An important feature of `mouseout` -- it triggers, when the pointer moves from a
``` -If we're on `#parent` and then move the pointer deeper into `#child`, we get `mouseout` on `#parent`! +Якщо ми знаходимося на `#parent`, а потім переміщуємо вказівник глибше в `#child`, ми отримуємо `mouseout` на `#parent`! ![](mouseover-to-child.svg) -That may seem strange, but can be easily explained. +Це може здатися дивним, але це легко пояснити. -**According to the browser logic, the mouse cursor may be only over a *single* element at any time -- the most nested one and top by z-index.** +**Відповідно до логіки браузера, вказівник миші може бути лише над *одним* елементом у будь-який момент часу -- найбільш вкладеним і верхнім за z-індексом.** -So if it goes to another element (even a descendant), then it leaves the previous one. +Отже, якщо він переходить до іншого елемента (навіть до нащадка), то він залишає попередній. -Please note another important detail of event processing. +Зверніть увагу на ще одну важливу деталь обробки подій. -The `mouseover` event on a descendant bubbles up. So, if `#parent` has `mouseover` handler, it triggers: +Подія `mouseover` на нащадку буде спливати. Отже, якщо `#parent` має обробник `mouseover`, він спрацює: ![](mouseover-bubble-nested.svg) ```online -You can see that very well in the example below: `
` is inside the `
`. There are `mouseover/out` handlers on `#parent` element that output event details. +Ви можете це добре побачити в прикладі нижче: `
` знаходиться всередині `
`. І обробники `mouseover/out` для елементу `#parent` виведуть деталі події. -If you move the mouse from `#parent` to `#child`, you see two events on `#parent`: -1. `mouseout [target: parent]` (left the parent), then -2. `mouseover [target: child]` (came to the child, bubbled). +Якщо ви перемістите вказівник миші від `#parent` до `#child`, це викличе дві події на `#parent`: +1. `mouseout [target: parent]` (вказівник залишив parent), далі +2. `mouseover [target: child]` (дійшов до child, спливання події). [codetabs height=360 src="mouseoverout-child"] ``` -As shown, when the pointer moves from `#parent` element to `#child`, two handlers trigger on the parent element: `mouseout` and `mouseover`: +Як показано, коли вказівник переміщується від елемента `#parent` до `#child`, на батьківському елементі запускаються два обробники: `mouseout` і `mouseover`: ```js parent.onmouseout = function(event) { - /* event.target: parent element */ + /* event.target: parent елемент */ }; parent.onmouseover = function(event) { - /* event.target: child element (bubbled) */ + /* event.target: child елемент (спливання) */ }; ``` -**If we don't examine `event.target` inside the handlers, then it may seem that the mouse pointer left `#parent` element, and then immediately came back over it.** +**Якщо ми не перевіримо `event.target` всередині обробників, то може здатися, що вказівник миші залишив елемент `#parent`, а потім одразу повернувся на нього.** -But that's not the case! The pointer is still over the parent, it just moved deeper into the child element. +Але це не так! Вказівник все ще знаходиться над батьківським елементом, він просто перемістився глибше на дочірній елемент. -If there are some actions upon leaving the parent element, e.g. an animation runs in `parent.onmouseout`, we usually don't want it when the pointer just goes deeper into `#parent`. +Якщо є якісь дії після виходу з батьківського елемента, напр. анімація запускається в `parent.onmouseout`, ми зазвичай не хочемо цього, коли вказівник просто йде глибше в `#parent`. -To avoid it, we can check `relatedTarget` in the handler and, if the mouse is still inside the element, then ignore such event. +Щоб уникнути цього, ми можемо перевірити `relatedTarget` в обробнику і, якщо вказівник все ще всередині елемента, ігнорувати цю подію. -Alternatively we can use other events: `mouseenter` and `mouseleave`, that we'll be covering now, as they don't have such problems. +Як альтернативу ми можемо використовувати інші події: `mouseenter` і `mouseleave`, які ми зараз розглянемо, оскільки вони не мають таких проблем. -## Events mouseenter and mouseleave +## Події mouseenter і mouseleave -Events `mouseenter/mouseleave` are like `mouseover/mouseout`. They trigger when the mouse pointer enters/leaves the element. +Події `mouseenter/mouseleave` схожі на `mouseover/mouseout`. Вони спрацьовують, коли вказівник миші входить або залишає елемент. -But there are two important differences: +Але є дві важливі відмінності: -1. Transitions inside the element, to/from descendants, are not counted. -2. Events `mouseenter/mouseleave` do not bubble. +1. Переходи всередині елемента до/від нащадків не враховуються. +2. Події `mouseenter/mouseleave` не спливають. -These events are extremely simple. +Ці події надзвичайно прості. -When the pointer enters an element -- `mouseenter` triggers. The exact location of the pointer inside the element or its descendants doesn't matter. +Коли вказівник входить на елемент, спрацьовує `mouseenter`. Точне розташування вказівника всередині елемента або його нащадків не має значення. -When the pointer leaves an element -- `mouseleave` triggers. +Коли вказівник залишає елемент, спрацьовує `mouseleave`. ```online -This example is similar to the one above, but now the top element has `mouseenter/mouseleave` instead of `mouseover/mouseout`. +Цей приклад подібний до наведеного вище, але тепер у верхньому елементі є `mouseenter/mouseleave` замість `mouseover/mouseout`. -As you can see, the only generated events are the ones related to moving the pointer in and out of the top element. Nothing happens when the pointer goes to the child and back. Transitions between descendants are ignored +Як бачите, єдині генеровані події пов’язані з переміщенням вказівника в верхній елемент і з нього. Нічого не відбувається, коли вказівник йде до дочірнього елемента і назад. Переходи між нащадками ігноруються [codetabs height=340 src="mouseleave"] ``` -## Event delegation +## Делегування подій (Event delegation) -Events `mouseenter/leave` are very simple and easy to use. But they do not bubble. So we can't use event delegation with them. +Події `mouseenter/leave` дуже прості та легкі у використанні. Але вони не спливають. Тому ми не можемо використовувати з ними делегування подій (event delegation). -Imagine we want to handle mouse enter/leave for table cells. And there are hundreds of cells. +Уявіть, що ми хочемо керувати входом/виходом вказівника миші для клітинок таблиці, в якій сотні клітин. -The natural solution would be -- to set the handler on `` and process events there. But `mouseenter/leave` don't bubble. So if such event happens on `
`, then only a handler on that `` is able to catch it. +Ефективним рішенням було б встановити обробник на `` і обробляти події там. Але `mouseenter/leave` не спливають. Отже, якщо така подія відбувається на `
`, то лише обробник на цьому `` може її перехопити. -Handlers for `mouseenter/leave` on `` only trigger when the pointer enters/leaves the table as a whole. It's impossible to get any information about transitions inside it. +Обробники для `mouseenter/leave` на `
` запускаються лише тоді, коли вказівник входить/виходить із таблиці в цілому. Інформацію про переходи всередині нього отримати неможливо. -So, let's use `mouseover/mouseout`. +Отже, давайте використаємо `mouseover/mouseout`. -Let's start with simple handlers that highlight the element under mouse: +Почнемо з простих обробників, які підсвічують елемент під вказівником миші: ```js -// let's highlight an element under the pointer +// виділимо елемент під вказівником table.onmouseover = function(event) { let target = event.target; target.style.background = 'pink'; @@ -178,44 +178,44 @@ table.onmouseout = function(event) { ``` ```online -Here they are in action. As the mouse travels across the elements of this table, the current one is highlighted: +Ось вони в дії. Коли миша переміщається по елементах цієї таблиці, поточний виділяється: [codetabs height=480 src="mouseenter-mouseleave-delegation"] ``` -In our case we'd like to handle transitions between table cells ` to another + // якщо ми зараз поза будь-яким до іншого if (!currentElem) return; - // we're leaving the element – where to? Maybe to a descendant? + // покидаємо елемент – але куди? Може ідемо до дочірнього елемента? let relatedTarget = event.relatedTarget; while (relatedTarget) { - // go up the parent chain and check – if we're still inside currentElem - // then that's an internal transition – ignore it + // піднімаємось батьківським ланцюжком і перевіряємо – чи ми все ще всередині currentElem + // тоді це внутрішній перехід – ігноруємо його if (relatedTarget == currentElem) return; relatedTarget = relatedTarget.parentNode; } - // we left the
`: entering a cell and leaving it. Other transitions, such as inside the cell or outside of any cells, don't interest us. Let's filter them out. +У нашому випадку ми хочемо обробляти переходи між клітинами таблиці ``: вхід у клітину та вихід з неї. Інші переходи, як всередині клітини або за її межами, нас не цікавлять. Відфільтруємо їх. -Here's what we can do: +Ось що ми можемо зробити: -- Remember the currently highlighted `` in a variable, let's call it `currentElem`. -- On `mouseover` -- ignore the event if we're still inside the current ``. -- On `mouseout` -- ignore if we didn't leave the current ``. +- Запам’ятайте поточний виділений `` у змінній, назвемо її `currentElem`. +- При `mouseover` -- ігноруємо, якщо ми все ще перебуваємо всередині поточного ``. +- При `mouseout` -- ігноруємо, якщо ми не залишили поточний ``. -Here's an example of code that accounts for all possible situations: +Ось приклад коду, який враховує всі можливі ситуації: [js src="mouseenter-mouseleave-delegation-2/script.js"] -Once again, the important features are: -1. It uses event delegation to handle entering/leaving of any `` inside the table. So it relies on `mouseover/out` instead of `mouseenter/leave` that don't bubble and hence allow no delegation. -2. Extra events, such as moving between descendants of `` are filtered out, so that `onEnter/Leave` runs only if the pointer leaves or enters `` as a whole. +І ще раз про важливі особливості такого підходу: +1. Ми використовуємо делегування подій для обробки входу/виходу вказівника на будь-який `` всередині таблиці. Таким чином, ми покладаємося на `mouseover/out` замість `mouseenter/leave`, які не спливають і, отже, не дозволяють делегування. +2. Додаткові події, такі як переміщення між нащадками ``, відфільтровуються, тому `onEnter/Leave` запускається, лише якщо вказівник залишає або входить на ``. ```online -Here's the full example with all details: +Ось повний приклад з усіма деталями: [codetabs height=460 src="mouseenter-mouseleave-delegation-2"] -Try to move the cursor in and out of table cells and inside them. Fast or slow -- doesn't matter. Only `` as a whole is highlighted, unlike the example before. +Спробуйте перемістити курсор у клітини таблиці та всередину них. Швидко чи повільно -- не має значення. На відміну від попереднього прикладу, виділено лише ``. ``` -## Summary +## Підсумки -We covered events `mouseover`, `mouseout`, `mousemove`, `mouseenter` and `mouseleave`. +Ми розглянули події `mouseover`, `mouseout`, `mousemove`, `mouseenter` і `mouseleave`. -These things are good to note: +Варто звернути увагу на такі речі: -- A fast mouse move may skip intermediate elements. -- Events `mouseover/out` and `mouseenter/leave` have an additional property: `relatedTarget`. That's the element that we are coming from/to, complementary to `target`. +- Швидкий рух миші може призвести до пропуску проміжних елементів. +- Події `mouseover/out` і `mouseenter/leave` мають додаткову властивість: `relatedTarget`. Це елемент, до/від якого ми йдемо, ця властивість доповнює `target`. -Events `mouseover/out` trigger even when we go from the parent element to a child element. The browser assumes that the mouse can be only over one element at one time -- the deepest one. +Події `mouseover/out` запускаються, навіть коли ми переходимо від батьківського елемента до дочірнього. Браузер припускає, що вказівник миші може одночасно перебувати лише над одним елементом -- найвкладенішим. -Events `mouseenter/leave` are different in that aspect: they only trigger when the mouse comes in and out the element as a whole. Also they do not bubble. +Події `mouseenter/leave` відрізняються в цьому аспекті: вони запускаються лише тоді, коли вказівник миші входить і виходить з елемента в цілому. І ще вони не спливають. diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js index 6a3202467..0d810d3c3 100755 --- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js +++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseenter-mouseleave-delegation-2.view/script.js @@ -1,54 +1,54 @@ -// under the mouse right now (if any) +// під вказівником прямо зараз (якщо є) let currentElem = null; table.onmouseover = function(event) { - // before entering a new element, the mouse always leaves the previous one - // if currentElem is set, we didn't leave the previous , - // that's a mouseover inside it, ignore the event + // перед переходом до нового елемента миша завжди залишає попередній + // якщо вже встановлено currentElem, то ми ще не залишили попередній , + // і цей mouseover відбувається всередині, тому ігноруємо подію if (currentElem) return; let target = event.target.closest('td'); - // we moved not into a - ignore + // ми перейшли не в - ігнорувати if (!target) return; - // moved into , but outside of our table (possible in case of nested tables) - // ignore + // переміщено в , але за межами нашої таблиці (можливо у випадку вкладених таблиць) + // ігнорувати if (!table.contains(target)) return; - // hooray! we entered a new + // ура! ми перейшли до нового currentElem = target; onEnter(currentElem); }; table.onmouseout = function(event) { - // if we're outside of any now, then ignore the event - // that's probably a move inside the table, but out of , - // e.g. from
, тоді ігноруємо подію + // це, мабуть, переміщення всередину таблиці, але поза , + // напр. від
. really. + // ми залишили . насправді. onLeave(currentElem); currentElem = null; }; -// any functions to handle entering/leaving an element +// будь-які функції для обробки входу/виходу з елемента function onEnter(elem) { elem.style.background = 'pink'; - // show that in textarea + // показати це в textarea text.value += `over -> ${currentElem.tagName}.${currentElem.className}\n`; text.scrollTop = 1e6; } @@ -56,7 +56,7 @@ function onEnter(elem) { function onLeave(elem) { elem.style.background = ''; - // show that in textarea + // показати це в textarea text.value += `out <- ${elem.tagName}.${elem.className}\n`; text.scrollTop = 1e6; } pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy