diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md index 13c387d2c..986f5641d 100644 --- a/1-js/02-first-steps/01-hello-world/article.md +++ b/1-js/02-first-steps/01-hello-world/article.md @@ -9,7 +9,7 @@ ## Тег "script" -Програми JavaScript можна вставити у будь-яку частину HTML документа, використовуючи тег ` ``` -Ми повинні вибрати або зовнішній ``. +- Скрипт з окремого файла можна вставити за допомогою ``. Існує набагато більше інформації про браузерні скрипти та їхню взаємодію з веб-сторінкою. Але майте на увазі, що ця частина посібника присвячена мові JavaScript, тому ми не повинні відволікатись на деталі реалізації в браузері. Ми будемо використовувати браузер як спосіб запуску JavaScript, що є дуже зручним для читання в Інтернеті, але це лише один із багатьох можливих варіантів. diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md index 37a05a35d..e4c54c2e1 100644 --- a/1-js/02-first-steps/02-structure/article.md +++ b/1-js/02-first-steps/02-structure/article.md @@ -4,9 +4,9 @@ ## Інструкції -Інструкції – це синтаксичні конструкції та команди, які виконують дії. +Інструкції -- це синтаксичні конструкції та команди, які виконують якісь дії. -Ми вже бачили інструкцію `alert('Привіт, світ!')`, яка показує повідомлення "Привіт, світ!". +Ми вже бачили інструкцію `alert('Привіт, світ!')`, яка показує повідомлення 'Привіт, світ!'. Можна писати стільки інструкцій, скільки завгодно. Інструкції можна розділяти крапкою з комою. @@ -132,7 +132,7 @@ alert('Світ'); ``` ```smart header="Використовуйте комбінації клавіш!" -У більшості редакторів рядок коду можна закоментувати, натиснувши комбінацію клавіш `key:Ctrl+/`, а щоби закоментувати декілька рядків – виділіть потрібні рядки та натисніть комбінацію клавіш `key:Ctrl+Shift+/`. У macOS потрібно натискати клавішу `key:Cmd` замість `key:Ctrl` і клавішу `key:Option` замість `key:Shift`. +У більшості редакторів рядок коду можна закоментувати, натиснувши комбінацію клавіш `key:Ctrl+/`, а щоби закоментувати декілька рядків -- виділіть потрібні рядки та натисніть комбінацію клавіш `key:Ctrl+Shift+/`. У macOS потрібно натискати клавішу `key:Cmd` замість `key:Ctrl` і клавішу `key:Option` замість `key:Shift`. ``` ````warn header="Вкладені коментарі не підтримуються!" diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md index f56df44d5..675212d63 100644 --- a/1-js/02-first-steps/03-strict-mode/article.md +++ b/1-js/02-first-steps/03-strict-mode/article.md @@ -41,12 +41,12 @@ alert("деякий код"); ```warn header="Неможливо скасувати `use strict`" Немає директиви на зразок `"no use strict"`, яка могла б вернути старий режим. -Як тільки ми увійшли в суворий режим, назад дороги немає. +Як тільки ми увімкнули суворий режим, назад дороги немає. ``` -## Консоль браузера +## Консоль розробника -Коли ви використовуєте [консоль розробника](info:devtools) для виконання коду, майте на увазі, що консоль усталено не використовує суворий режим. +Коли ви використовуєте [консоль розробника](info:devtools) для виконання коду, майте на увазі, що консоль типово не використовує суворий режим. В тих випадках, коли `use strict` впливає на роботу коду, ви отримаєте невірні результати в консолі. @@ -62,7 +62,7 @@ alert("деякий код"); Це працюватиме в більшості браузерів, зокрема в Firefox і Chrome. -Якщо не спрацює, наприклад, в старих браузерах, тоді найнадійнішим варіантом буде використати `use strict` всередині функції-обгортки (хоч це, звичайно, виглядатиме потворно). Ось так: +Якщо не спрацює, наприклад, в старих браузерах, тоді найнадійнішим варіантом буде використати `use strict` всередині функції-обгортки (хоч це, звичайно, виглядатиме дивно). Ось так: ```js (function() { @@ -78,12 +78,12 @@ alert("деякий код"); Одні можуть порекомендувати ставити `"use strict"` на початку скриптів... Але знаєте, що круто? -Сучасний JavaScript підтримує "класи" і "модулі" – просунуті структури мови (ми їх, звичайно, будемо вивчати), які автоматично вмикають `use strict`. Тому, якщо ми використовуємо ці структури, нам не потрібно прописувати директиву `"use strict"`. +Сучасний JavaScript підтримує "класи" і "модулі" -- просунуті конструкції мови (ми їх, звичайно, будемо вивчати), які автоматично вмикають `use strict`. Тому, якщо ми використовуємо їх, нам не потрібно прописувати директиву `"use strict"`. **Отож зараз бажано ставити `"use strict";` на початку скриптів. Але пізніше, коли наш код "доросте" до класів і модулів, ми зможемо пропускати цю директиву.** -Зараз ми знаємо про `use strict` в загальному. +Зараз ми дізнались основне про `use strict`. -У наступних розділах, в процесі вивчення особливостей мови, ми помітимо відмінності між суворим і усталеним режимами. На щастя, їх не багато, і вони справді роблять наше життя кращим. +У наступних розділах, в процесі вивчення особливостей мови, ми поговоримо про відмінності між суворим і типовим режимами. На щастя, їх не багато, але вони дійсно змінюють наше життя на краще. Всі приклади в цьому посібнику працюють в суворому режимі, окрім випадків (дуже рідкісних), коли вказано зворотнє. diff --git a/2-ui/99-ui-misc/02-selection-range/article.md b/2-ui/99-ui-misc/02-selection-range/article.md index 819bcba29..f1fc8d176 100644 --- a/2-ui/99-ui-misc/02-selection-range/article.md +++ b/2-ui/99-ui-misc/02-selection-range/article.md @@ -4,37 +4,37 @@ libs: --- -# Selection and Range +# Selection і Range -In this chapter we'll cover selection in the document, as well as selection in form fields, such as ``. +У цьому розділі ми розглянемо виділення у документі та в полях форми, наприклад, в ``. -JavaScript can access an existing selection, select/deselect DOM nodes as a whole or partially, remove the selected content from the document, wrap it into a tag, and so on. +JavaScript може отримати доступ до наявного виділення тексту, вибирати/скасовувати виділення вузлів DOM повністю або частково, видаляти виділений вміст із документа, або обгорнути його в тег тощо. -You can find some recipes for common tasks at the end of the chapter, in "Summary" section. Maybe that covers your current needs, but you'll get much more if you read the whole text. +В кінці розділу ми підготували кілька готових рішень для типових задач (розділ "Підсумки"). Цілком можливо, цього буде достатньо щоб задовольнити всі ваші поточні потреби, проте ви отримаєте набагато більше, якщо прочитаєте статтю повністю. -The underlying `Range` and `Selection` objects are easy to grasp, and then you'll need no recipes to make them do what you want. +З об’єктами `Range` та `Selection` можна розібратись досить легко, і тоді вам не знадобляться готові рішення для розв'язання задач. ## Range -The basic concept of selection is [Range](https://dom.spec.whatwg.org/#ranges), that is essentially a pair of "boundary points": range start and range end. +Основою виділення є [Range](https://dom.spec.whatwg.org/#ranges), який по своїй суті є парою "граничних точок": початком і кінцем діапазону. -A `Range` object is created without parameters: +Об'єкт `Range`(діапазон) створюється без параметрів: ```js let range = new Range(); ``` -Then we can set the selection boundaries using `range.setStart(node, offset)` and `range.setEnd(node, offset)`. +Далі ми можемо встановити межі виділення за допомогою `range.setStart(node, offset)` і `range.setEnd(node, offset)`. -As you might guess, further we'll use the `Range` objects for selection, but first let's create few such objects. +Як ви могли здогадатися, ми будемо використовувати об’єкти `Range` для виділення, але спочатку давайте створимо декілька таких об’єктів. -### Selecting the text partially +### Часткове виділення тексту -The interesting thing is that the first argument `node` in both methods can be either a text node or an element node, and the meaning of the second argument depends on that. +Цікаво те, що перший аргумент `node` в обох методах може бути або текстовим вузлом, або вузлом елементом, і від цього залежить значення другого аргументу. -**If `node` is a text node, then `offset` must be the position in its text.** +**Якщо `node` -- це текстовий вузол, то `offset` має бути позицією в його тексті.** -For example, given the element `

Hello

`, we can create the range containing the letters "ll" as follows: +Наприклад, в елементі `

Hello

`, ми можемо створити діапазон, що містить літери "ll" таким чином: ```html run

Hello

@@ -43,28 +43,28 @@ For example, given the element `

Hello

`, we can create the range containin range.setStart(p.firstChild, 2); range.setEnd(p.firstChild, 4); - // toString of a range returns its content as text + // toString діапазону повертає його вміст як текст console.log(range); // ll ``` -Here we take the first child of `

` (that's the text node) and specify the text positions inside it: +Тут ми беремо перший дочірній елемент всередині `

` (це текстовий вузол) і вказуємо позиції в тексті для виділення: ![](range-hello-1.svg) -### Selecting element nodes +### Виділення вузлів елементів -**Alternatively, if `node` is an element node, then `offset` must be the child number.** +**Проте, якщо `node` є вузлом елементом, тоді `offset` має бути номером дочірнього елементу.** -That's handy for making ranges that contain nodes as a whole, not stop somewhere inside their text. +Це зручно для створення діапазонів, які містять вузли в цілому, а не зупиняються десь усередині їхнього тексту. -For example, we have a more complex document fragment: +Наприклад, маємо більш складний фрагмент документу: ```html autorun

Example: italic and bold

``` -Here's its DOM structure with both element and text nodes: +Ось його структура DOM з вузлами елементами та текстовими вузлами:
@@ -102,20 +102,20 @@ let selectPDomtree = { drawHtmlTree(selectPDomtree, 'div.select-p-domtree', 690, 320); -Let's make a range for `"Example: italic"`. +Зробимо діапазон для `"Example: italic"`. -As we can see, this phrase consists of exactly two children of `

`, with indexes `0` and `1`: +Як ми бачимо, ця фраза складається рівно з двох нащадків `

` з індексами `0` і `1`: ![](range-example-p-0-1.svg) -- The starting point has `

` as the parent `node`, and `0` as the offset. +- Початкова точка має `

` як батьківський `node` і `0` як `offset`. - So we can set it as `range.setStart(p, 0)`. -- The ending point also has `

` as the parent `node`, but `2` as the offset (it specifies the range up to, but not including `offset`). + Тому ми можемо встановити його як `range.setStart(p, 0)`. +- Кінцева точка також має `

` як батьківський `node`, але `2` як `offset` (вона вказує діапазон до, але не включаючи `offset`). - So we can set it as `range.setEnd(p, 2)`. + Тому ми можемо встановити його як `range.setEnd(p, 2)`. -Here's the demo. If you run it, you can see that the text gets selected: +Нижче ми підготували приклад з демонстрацією. Якщо ви запустите його, то текст буде виділено: ```html run

Example: italic and bold

@@ -128,15 +128,15 @@ Here's the demo. If you run it, you can see that the text gets selected: range.setEnd(p, 2); */!* - // toString of a range returns its content as text, without tags + // toString діапазону повертає його вміст у вигляді тексту без тегів console.log(range); // Example: italic - // apply this range for document selection (explained later below) + // застосуємо цей діапазон для виділення в document (пояснюється нижче) document.getSelection().addRange(range); ``` -Here's a more flexible test stand where you can set range start/end numbers and explore other variants: +Ось гнучкіший тестовий приклад, де ви можете встановити початкові/кінцеві точки діапазону та дослідити інші варіанти: ```html run autorun

Example: italic and bold

@@ -152,32 +152,32 @@ From – To ` first child (taking all but two first letters of "Example: ") -- ends at the position 3 in `` first child (taking first three letters of "bold", but no more): +Нам потрібно створити діапазон, який: +- починається з позиції 2 у першому дочірньому вузлі елемента `

` (беручи всі, крім двох перших літер "Example: ") +- закінчується на позиції 3 у `` в першому дочірньому вузлі (бере перші три літери "bold", але не більше): ```html run

Example: italic and bold

@@ -190,75 +190,75 @@ We need to create a range, that: console.log(range); // ample: italic and bol - // use this range for selection (explained later) + // застосуємо цей діапазон для виділення в document (пояснюється нижче) window.getSelection().addRange(range); ``` -As you can see, it's fairly easy to make a range of whatever we want. +Як бачите, досить легко створити діапазон для будь-чого. -If we'd like to take nodes as a whole, we can pass elements in `setStart/setEnd`. Otherwise, we can work on the text level. +Ба більше, якщо ми хочемо взяти вузли як ціле, треба передати елементи замість текстових вузлів в `setStart/setEnd`. Інакше це буде працювати на рівні тексту. -## Range properties +## Властивості Range -The range object that we created in the example above has following properties: +Об’єкт діапазону, який ми використовували у прикладі вище, має такі властивості: ![](range-example-p-2-b-3-range.svg) -- `startContainer`, `startOffset` -- node and offset of the start, - - in the example above: first text node inside `

` and `2`. -- `endContainer`, `endOffset` -- node and offset of the end, - - in the example above: first text node inside `` and `3`. -- `collapsed` -- boolean, `true` if the range starts and ends on the same point (so there's no content inside the range), - - in the example above: `false` -- `commonAncestorContainer` -- the nearest common ancestor of all nodes within the range, - - in the example above: `

` +- `startContainer`, `startOffset` -- node і offset початку, + - у наведеному вище прикладі: перший текстовий вузол всередині `

` і `2`. +- `endContainer`, `endOffset` -- node і offset кінця, + - у прикладі вище: перший текстовий вузол всередині `` і `3`. +- `collapsed` -- значення логічного типу, `true` якщо діапазон починається і закінчується в одній точці (тому всередині діапазону немає вмісту), + - у прикладі вище: `false` +- `commonAncestorContainer` -- найближчий спільний предок усіх вузлів у діапазоні, + - у прикладі вище: `

` -## Range selection methods +## Методи виділення в Range -There are many convenient methods to manipulate ranges. +Існує багато зручних методів по роботі з діапазонами. -We've already seen `setStart` and `setEnd`, here are other similar methods. +Ми вже бачили `setStart` і `setEnd`, ось інші подібні методи. -Set range start: +Встановити початок діапазону: -- `setStart(node, offset)` set start at: position `offset` in `node` -- `setStartBefore(node)` set start at: right before `node` -- `setStartAfter(node)` set start at: right after `node` +- `setStart(node, offset)` встановити початок у: позиції `offset` в `node` +- `setStartBefore(node)` встановити початок: безпосередньо перед `node` +- `setStartAfter(node)` встановити початок: відразу після `node` -Set range end (similar methods): +Встановити кінець діапазону (подібні методи): -- `setEnd(node, offset)` set end at: position `offset` in `node` -- `setEndBefore(node)` set end at: right before `node` -- `setEndAfter(node)` set end at: right after `node` +- `setEnd(node, offset)` встановити кінець у: позиції `offset` в `node` +- `setEndBefore(node)` встановити кінець: безпосередньо перед `node` +- `setEndAfter(node)` встановити кінець: одразу після `node` -Technically, `setStart/setEnd` can do anything, but more methods provide more convenience. +Технічно `setStart/setEnd` можуть робити що завгодно, але більше методів забезпечують більшу зручність. -In all these methods, `node` can be both a text or element node: for text nodes `offset` skips that many of characters, while for element nodes that many child nodes. +У всіх цих методах `node` може бути як текстовим, так і вузлом елементом: для текстових вузлів `offset` пропускає таку кількість символів, тоді як для вузлів елементів стільки ж дочірніх вузлів. -Even more methods to create ranges: -- `selectNode(node)` set range to select the whole `node` -- `selectNodeContents(node)` set range to select the whole `node` contents -- `collapse(toStart)` if `toStart=true` set end=start, otherwise set start=end, thus collapsing the range -- `cloneRange()` creates a new range with the same start/end +Ще більше методів створення діапазонів: +- `selectNode(node)` встановити діапазон для виділення всього `node` +- `selectNodeContents(node)` встановити діапазон для виділення всього вмісту `node` +- `collapse(toStart)` якщо `toStart=true` встановити кінець=початок, інакше встановити початок=кінець, таким чином згорнувши діапазон +- `cloneRange()` створює новий діапазон із тим самим початком/кінцем -## Range editing methods +## Методи редагування Range -Once the range is created, we can manipulate its content using these methods: +Після створення діапазону ми можемо маніпулювати його вмістом за допомогою таких методів: -- `deleteContents()` -- remove range content from the document -- `extractContents()` -- remove range content from the document and return as [DocumentFragment](info:modifying-document#document-fragment) -- `cloneContents()` -- clone range content and return as [DocumentFragment](info:modifying-document#document-fragment) -- `insertNode(node)` -- insert `node` into the document at the beginning of the range -- `surroundContents(node)` -- wrap `node` around range content. For this to work, the range must contain both opening and closing tags for all elements inside it: no partial ranges like `abc`. +- `deleteContents()` -- видалити вміст діапазону з документа +- `extractContents()` -- видалити вміст діапазону з документа та повернути як [DocumentFragment](info:modifying-document#document-fragment) +- `cloneContents()` -- клонувати вміст діапазону та повернути як [DocumentFragment](info:modifying-document#document-fragment) +- `insertNode(node)` -- вставити `node` в документ на початку діапазону +- `surroundContents(node)` -- обернути `node` навколо вмісту діапазону. Щоб це працювало, діапазон має містити відкриваючі та закриваючі теги для всіх елементів у ньому: жодних часткових діапазонів, як-от `abc`. -With these methods we can do basically anything with selected nodes. +За допомогою цих методів ми можемо робити що завгодно з виділенними вузлами. -Here's the test stand to see them in action: +Ось тестовий приклад, щоб побачити їх у дії: ```html run refresh autorun height=260 -Click buttons to run methods on the selection, "resetExample" to reset it. +Натисніть кнопки, щоб запустити методи для виділення, "resetExample", щоб скинути його.

Example: italic and bold

@@ -266,7 +266,7 @@ Click buttons to run methods on the selection, "resetExample" to reset it. ``` -There also exist methods to compare ranges, but these are rarely used. When you need them, please refer to the [spec](https://dom.spec.whatwg.org/#interface-range) or [MDN manual](mdn:/api/Range). +Існують також методи порівняння діапазонів, але вони використовуються рідко. Коли вони вам знадобляться, ви можете з ними познайомитись ось тут [spec](https://dom.spec.whatwg.org/#interface-range), або тут [MDN manual](mdn:/api/Range). ## Selection -`Range` is a generic object for managing selection ranges. Although, creating a `Range` doesn't mean that we see a selection on screen. +`Range` -- це загальний об'єкт для керування діапазонами виділення. Хоча створення `Range` не означає, що ми бачимо виділення на екрані. -We may create `Range` objects, pass them around -- they do not visually select anything on their own. +Ми можемо створювати об’єкти `Range`, передавати їх -- вони самі по собі нічого візуально не виділяють. -The document selection is represented by `Selection` object, that can be obtained as `window.getSelection()` or `document.getSelection()`. A selection may include zero or more ranges. At least, the [Selection API specification](https://www.w3.org/TR/selection-api/) says so. In practice though, only Firefox allows to select multiple ranges in the document by using `key:Ctrl+click` (`key:Cmd+click` for Mac). +Виділення в документі представлено об’єктом `Selection`, який можна отримати як `window.getSelection()` або `document.getSelection()`. Виділення може містити нуль або більше діапазонів. Принаймні, [Selection API specification](https://www.w3.org/TR/selection-api/) каже саме так. Однак на практиці лише Firefox дозволяє вибирати кілька діапазонів у документі за допомогою `key:Ctrl+click` (`key:Cmd+click` для Mac). -Here's a screenshot of a selection with 3 ranges, made in Firefox: +Ось скріншот виділення з 3-ьома діапазонами, зроблений у Firefox: ![](selection-firefox.svg) -Other browsers support at maximum 1 range. As we'll see, some of `Selection` methods imply that there may be many ranges, but again, in all browsers except Firefox, there's at maximum 1. +Інші браузери підтримують максимум 1 діапазон. Як ми побачимо, деякі з методів `Selection` означають, що може бути багато діапазонів, але знову ж таки, у всіх браузерах, крім Firefox, їх не більше 1. -Here's a small demo that shows the current selection (select something and click) as text: +Ось невеликий приклад, який показує поточне виділення (виділіть щось і натисніть) як текст: -## Selection properties +## Властивості Selection -As said, a selection may in theory contain multiple ranges. We can get these range objects using the method: +Як було сказано, об'єкт `Selection` теоретично може містити кілька діапазонів. Ми можемо отримати ці діапазони за допомогою методу: -- `getRangeAt(i)` -- get i-th range, starting from `0`. In all browsers except Firefox, only `0` is used. +- `getRangeAt(i)` -- отримати i-й діапазон, починаючи з `0`. У всіх браузерах, крім Firefox, використовується лише `0`. -Also, there exist properties that often provide better convenience. +Крім того, існують зручніші властивості. -Similar to a range, a selection object has a start, called "anchor", and the end, called "focus". +Подібно до діапазону, об’єкт виділення має початок, який називається "anchor", і кінець, який називається "focus". -The main selection properties are: +Основними властивостями `Selection` є: -- `anchorNode` -- the node where the selection starts, -- `anchorOffset` -- the offset in `anchorNode` where the selection starts, -- `focusNode` -- the node where the selection ends, -- `focusOffset` -- the offset in `focusNode` where the selection ends, -- `isCollapsed` -- `true` if selection selects nothing (empty range), or doesn't exist. -- `rangeCount` -- count of ranges in the selection, maximum `1` in all browsers except Firefox. +- `anchorNode` -- вузол, де починається виділення, +- `anchorOffset` -- зміщення в `anchorNode`, де починається виділення, +- `focusNode` -- вузол, де закінчується виділення, +- `focusOffset` -- зсув у `focusNode`, де закінчується виділення, +- `isCollapsed` -- `true` якщо нічого не виділено (порожній діапазон) або не існує. +- `rangeCount` -- кількість діапазонів у виділенні, максимум `1` у всіх браузерах, крім Firefox. -```smart header="Selection end/start vs Range" +```smart header="Selection кінець/початок у порівнянні з Range" -There's an important differences of a selection anchor/focus compared with a `Range` start/end. +Існують важливі відмінності `Selection` anchor/focus порівняно з `Range` start/end. -As we know, `Range` objects always have their start before the end. +Як ми знаємо, об’єкти `Range` завжди мають початок(start) перед кінцем(end). -For selections, that's not always the case. +Для `Selection` це не завжди так. -Selecting something with a mouse can be done in both directions: either "left-to-right" or "right-to-left". +Виділяти щось за допомогою миші можна в обох напрямках: або "зліва направо", або "справа наліво". -In other words, when the mouse button is pressed, and then it moves forward in the document, then its end (focus) will be after its start (anchor). +Іншими словами, коли кнопку миші натиснуто, а потім вона переміщується вперед у документі, то її кінець (focus) буде після її початку (anchor). -E.g. if the user starts selecting with mouse and goes from "Example" to "italic": +Наприклад якщо користувач починає виділяти мишею та переходить від "Example" до "italic": ![](selection-direction-forward.svg) -...But the same selection could be done backwards: starting from "italic" to "Example" (backward direction), then its end (focus) will be before the start (anchor): +...Але те саме виділення можна зробити і в зворотному напрямку: починаючи від "italic" до "Example" (напрямок назад), тоді його кінець (focus) буде перед початком (anchor): ![](selection-direction-backward.svg) ``` -## Selection events +## Події Selection -There are events on to keep track of selection: +Існують події, щоб слідкувати за виділенням: -- `elem.onselectstart` -- when a selection *starts* specifically on element `elem` (or inside it). For instance, when the user presses the mouse button on it and starts to move the pointer. - - Preventing the default action cancels the selection start. So starting a selection from this element becomes impossible, but the element is still selectable. The visitor just needs to start the selection from elsewhere. -- `document.onselectionchange` -- whenever a selection changes or starts. - - Please note: this handler can be set only on `document`, it tracks all selections in it. +- `elem.onselectstart` -- коли виділення *починається* саме на елементі `elem` (або всередині нього). Наприклад, коли користувач натискає на ньому кнопку миші та починає рухати вказівник. + - Запобігання типової дії скасовує початок виділення. Таким чином, почати виділення з цього елемента стає неможливо, але елемент все ще доступний для виділення загалом. Користувачу просто потрібно почати виділення з іншого місця. +- `document.onselectionchange` -- кожного разу, коли виділення змінюється або починається. + - Зверніть увагу: цей обробник можна встановити лише на `document`, він відстежує всі виділення в ньому. -### Selection tracking demo +### Приклад з відстеженням Selection -Here's a small demo. It tracks the current selection on the `document` and shows its boundaries: +Ось невелика демонстрація, яка показує поточний вибір та його межі у `document`: ```html run height=80

Select me: italic and bold

@@ -396,21 +396,21 @@ From – To let {anchorNode, anchorOffset, focusNode, focusOffset} = selection; - // anchorNode and focusNode are text nodes usually + // anchorNode і focusNode зазвичай є текстовими вузлами from.value = `${anchorNode?.data}, offset ${anchorOffset}`; to.value = `${focusNode?.data}, offset ${focusOffset}`; }; ``` -### Selection copying demo +### Виділення з копіюванням -There are two approaches to copying the selected content: +Є два підходи до копіювання виділенного вмісту: -1. We can use `document.getSelection().toString()` to get it as text. -2. Otherwise, to copy the full DOM, e.g. if we need to keep formatting, we can get the underlying ranges with `getRangeAt(...)`. A `Range` object, in turn, has `cloneContents()` method that clones its content and returns as `DocumentFragment` object, that we can insert elsewhere. +1. Ми можемо використати `document.getSelection().toString()`, щоб отримати його як текст. +2. В іншому випадку, щоб скопіювати повний DOM, напр. якщо нам потрібно продовжити форматування, ми можемо отримати виділенні діапазони за допомогою `getRangeAt(...)`. Об’єкт `Range`, у свою чергу, має метод `cloneContents()`, який клонує його вміст і повертає як об’єкт `DocumentFragment`, який ми можемо вставити в інше місце. -Here's the demo of copying the selected content both as text and as DOM nodes: +Ось приклад копіювання виділеного вмісту як тексту і як вузлів DOM: ```html run height=100

Select me: italic and bold

@@ -425,104 +425,104 @@ As text: cloned.innerHTML = astext.innerHTML = ""; - // Clone DOM nodes from ranges (we support multiselect here) + // Клонувати вузли DOM із діапазонів (тут ми підтримуємо множинне виділення) for (let i = 0; i < selection.rangeCount; i++) { cloned.append(selection.getRangeAt(i).cloneContents()); } - // Get as text + // Отримати як текст astext.innerHTML += selection; }; ``` -## Selection methods +## Методи Selection -We can work with the selection by adding/removing ranges: +Ми можемо працювати з виділенням, додаючи/вилучаючи діапазони: -- `getRangeAt(i)` -- get i-th range, starting from `0`. In all browsers except Firefox, only `0` is used. -- `addRange(range)` -- add `range` to selection. All browsers except Firefox ignore the call, if the selection already has an associated range. -- `removeRange(range)` -- remove `range` from the selection. -- `removeAllRanges()` -- remove all ranges. -- `empty()` -- alias to `removeAllRanges`. +- `getRangeAt(i)` -- отримати i-й діапазон, починаючи з `0`. У всіх браузерах, крім Firefox, використовується лише `0`. +- `addRange(range)` -- додати `range` до виділення. Усі браузери, крім Firefox, ігнорують виклик, якщо у виділенні вже є діапазон. +- `removeRange(range)` -- видалити `range` з виділення. +- `removeAllRanges()` -- видалити всі діапазони. +- `empty()` -- метод аналогічний `removeAllRanges`. -There are also convenience methods to manipulate the selection range directly, without intermediate `Range` calls: +Існують також зручні методи для безпосереднього керування діапазоном вибору без проміжних викликів `Range`: -- `collapse(node, offset)` -- replace selected range with a new one that starts and ends at the given `node`, at position `offset`. -- `setPosition(node, offset)` -- alias to `collapse`. -- `collapseToStart()` - collapse (replace with an empty range) to selection start, -- `collapseToEnd()` - collapse to selection end, -- `extend(node, offset)` - move focus of the selection to the given `node`, position `offset`, -- `setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)` - replace selection range with the given start `anchorNode/anchorOffset` and end `focusNode/focusOffset`. All content in-between them is selected. -- `selectAllChildren(node)` -- select all children of the `node`. -- `deleteFromDocument()` -- remove selected content from the document. -- `containsNode(node, allowPartialContainment = false)` -- checks whether the selection contains `node` (partially if the second argument is `true`) +- `collapse(node, offset)` -- замінити діапазон виділення на новий, який починається і закінчується на заданому `node`, на позиції `offset`. +- `setPosition(node, offset)` -- метод аналогічний `collapse`. +- `collapseToStart()` -- згорнути (замінити порожнім діапазоном) до початку виділення, +- `collapseToEnd()` -- згорнути до кінця виділення, +- `extend(node, offset)` -- перемістити фокус виділення на заданий `node`, положення `offset`, +- `setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)` -- замінити діапазон виділення заданим початковим `anchorNode/anchorOffset` і кінцевим `focusNode/focusOffset`. Весь вміст між ними буде виділено. +- `selectAllChildren(node)` -- виділити всі дочірні елементи `node`. +- `deleteFromDocument()` -- видалити виділений вміст із документа. +- `containsNode(node, allowPartialContainment = false)` -- перевіряє, чи містить виділення заданий `node` (або частково, якщо другий аргумент `true`) -For most tasks these methods are just fine, there's no need to access the underlying `Range` object. +Для більшості завдань ці методи чудово підходять, немає необхідності звертатися до базового об’єкта `Range`. -For example, selecting the whole contents of the paragraph `

`: +Наприклад, виділення всього вмісту абзацу `

`: ```html run

Select me: italic and bold

``` -The same thing using ranges: +Те саме з використанням діапазонів: ```html run

Select me: italic and bold

``` -```smart header="To select something, remove the existing selection first" -If a document selection already exists, empty it first with `removeAllRanges()`. And then add ranges. Otherwise, all browsers except Firefox ignore new ranges. +```smart header="Щоб зробити нове виділення, спочатку приберіть поточне" +Якщо вже щось виділене, спочатку приберіть це за допомогою `removeAllRanges()`. А потім додавайте діапазони. В іншому випадку всі браузери, крім Firefox, ігнорують нові діапазони. -The exception is some selection methods, that replace the existing selection, such as `setBaseAndExtent`. +Виняток становлять деякі методи, які замінюють існуюче виділення, наприклад `setBaseAndExtent`. ``` -## Selection in form controls +## Виділення в інтерактивних елементах форми -Form elements, such as `input` and `textarea` provide [special API for selection](https://html.spec.whatwg.org/#textFieldSelection), without `Selection` or `Range` objects. As an input value is a pure text, not HTML, there's no need for such objects, everything's much simpler. +Такі елементи форми, як `input` і `textarea`, надають [спеціальний API для виділення](https://html.spec.whatwg.org/#textFieldSelection) без об’єктів `Selection` або `Range`. Ба більше, оскільки на вході завжди чистий текст, а не HTML, такі об’єкти просто не потрібні, все працює значно простіше. -Properties: -- `input.selectionStart` -- position of selection start (writeable), -- `input.selectionEnd` -- position of selection end (writeable), -- `input.selectionDirection` -- selection direction, one of: "forward", "backward" or "none" (if e.g. selected with a double mouse click), +Властивості: +- `input.selectionStart` -- позиція початку виділення (працює на запис), +- `input.selectionEnd` -- позиція кінця виділення (працює на запис), +- `input.selectionDirection` -- напрямок виділення, одне з: "forward", "backward" або "none" (якщо напр. виділено подвійним клацанням миші), -Events: -- `input.onselect` -- triggers when something is selected. +Події: +- `input.onselect` -- запускається, коли щось виділено. -Methods: +Методи: -- `input.select()` -- selects everything in the text control (can be `textarea` instead of `input`), -- `input.setSelectionRange(start, end, [direction])` -- change the selection to span from position `start` till `end`, in the given direction (optional). -- `input.setRangeText(replacement, [start], [end], [selectionMode])` -- replace a range of text with the new text. +- `input.select()` -- виділяє все в текстовому елементі (може бути `textarea` замість `input`), +- `input.setSelectionRange(start, end, [direction])` -- змінити виділення на діапазон від позиції `start` до `end` у вказаному `direction` (необов’язковий параметер). +- `input.setRangeText(replacement, [start], [end], [selectionMode])` -- замінити діапазон тексту новим текстом. - Optional arguments `start` and `end`, if provided, set the range start and end, otherwise user selection is used. + Необов’язкові аргументи `start` і `end`, якщо вони надані, встановлюють початок і кінець діапазону, інакше використовується виділення від користувача. - The last argument, `selectionMode`, determines how the selection will be set after the text has been replaced. The possible values are: + Останній аргумент, `selectionMode`, визначає, як буде встановлено виділення після заміни тексту. Можливі значення: - - `"select"` -- the newly inserted text will be selected. - - `"start"` -- the selection range collapses just before the inserted text (the cursor will be immediately before it). - - `"end"` -- the selection range collapses just after the inserted text (the cursor will be right after it). - - `"preserve"` -- attempts to preserve the selection. This is the default. + - `"select"` -- буде виділено щойно вставлений текст. + - `"start"` -- діапазон виділення згортається безпосередньо перед вставленим текстом (курсор буде перед ним). + - `"end"` -- діапазон виділення згортається відразу після вставленого тексту (курсор буде відразу за ним). + - `"preserve"` -- спробує зберегти виділення. Це типове значення. -Now let's see these methods in action. +Тепер давайте подивимося на ці методи в дії. -### Example: tracking selection +### Приклад: відстеження виділення -For example, this code uses `onselect` event to track selection: +Наприклад, цей код використовує подію `onselect` для відстеження виділення: ```html run autorun