From 3cad6627403fb2feadcbc2d951e91e999039c0f3 Mon Sep 17 00:00:00 2001 From: ltlaitoff Date: Fri, 15 Sep 2023 16:51:21 +0300 Subject: [PATCH 01/11] =?UTF-8?q?feat(1-js):=20Changed=20all=20apostrophes?= =?UTF-8?q?=20from=20=E2=80=99=20to=20'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/01-getting-started/1-intro/article.md | 14 +- 1-js/01-getting-started/4-devtools/article.md | 2 +- 1-js/02-first-steps/02-structure/article.md | 4 +- .../2-declare-variables/solution.md | 6 +- 1-js/02-first-steps/04-variables/article.md | 6 +- 1-js/02-first-steps/05-types/article.md | 26 ++-- .../06-alert-prompt-confirm/article.md | 2 +- .../07-type-conversions/article.md | 8 +- 1-js/02-first-steps/08-operators/article.md | 16 +- 1-js/02-first-steps/09-comparison/article.md | 2 +- 1-js/02-first-steps/10-ifelse/article.md | 4 +- .../11-logical-operators/article.md | 6 +- .../12-nullish-coalescing-operator/article.md | 16 +- .../6-repeat-until-correct/task.md | 2 +- .../solution.md | 2 +- .../15-function-basics/article.md | 18 +-- .../18-javascript-specials/article.md | 16 +- .../01-debugging-chrome/article.md | 2 +- 1-js/03-code-quality/04-ninja-code/article.md | 30 ++-- .../3-pow-test-wrong/solution.md | 2 +- .../05-testing-mocha/article.md | 4 +- 1-js/03-code-quality/06-polyfills/article.md | 4 +- .../01-object/2-hello-object/task.md | 4 +- .../01-object/3-is-empty/solution.md | 2 +- .../01-object/3-is-empty/task.md | 2 +- .../01-object/5-sum-object/task.md | 6 +- .../01-object/8-multiply-numeric/task.md | 4 +- 1-js/04-object-basics/01-object/article.md | 82 +++++----- .../02-object-copy/article.md | 78 +++++----- .../03-garbage-collection/article.md | 62 ++++---- .../4-object-property-this/solution.md | 6 +- .../4-object-property-this/task.md | 4 +- .../04-object-methods/7-calculator/task.md | 2 +- .../8-chain-calls/solution.md | 2 +- .../04-object-methods/article.md | 68 ++++----- .../1-two-functions-one-object/solution.md | 4 +- .../1-two-functions-one-object/task.md | 2 +- .../2-calculator-constructor/task.md | 4 +- .../06-constructor-new/3-accumulator/task.md | 2 +- .../06-constructor-new/article.md | 48 +++--- .../07-optional-chaining/article.md | 22 +-- 1-js/04-object-basics/08-symbol/article.md | 38 ++--- .../09-object-toprimitive/article.md | 80 +++++----- 1-js/04-object-basics/index.md | 2 +- .../01-primitives-methods/article.md | 36 ++--- .../9-random-int-min-max/solution.md | 2 +- 1-js/05-data-types/02-number/article.md | 18 +-- .../04-array/1-item-value/solution.md | 2 +- .../04-array/3-call-array-this/solution.md | 2 +- 1-js/05-data-types/04-array/article.md | 52 +++---- .../05-array-methods/10-average-age/task.md | 2 +- .../05-array-methods/12-reduce-object/task.md | 4 +- .../6-array-get-names/task.md | 2 +- .../05-data-types/05-array-methods/article.md | 2 +- 1-js/05-data-types/06-iterable/article.md | 82 +++++----- 1-js/05-data-types/07-map-set/article.md | 76 +++++----- .../01-recipients-read/solution.md | 4 +- .../01-recipients-read/task.md | 4 +- .../02-recipients-when-read/solution.md | 2 +- .../02-recipients-when-read/task.md | 4 +- .../08-weakmap-weakset/article.md | 84 +++++------ .../01-sum-salaries/task.md | 4 +- .../02-count-properties/task.md | 2 +- .../09-keys-values-entries/article.md | 18 +-- .../1-destruct-user/task.md | 2 +- .../6-max-salary/task.md | 6 +- .../10-destructuring-assignment/article.md | 58 +++---- .../11-date/1-new-date/solution.md | 2 +- 1-js/05-data-types/11-date/1-new-date/task.md | 2 +- .../11-date/6-get-seconds-today/solution.md | 2 +- .../8-format-date-relative/solution.md | 2 +- 1-js/05-data-types/11-date/article.md | 30 ++-- .../12-json/1-serialize-object/task.md | 2 +- .../2-serialize-event-circular/task.md | 2 +- 1-js/05-data-types/12-json/article.md | 68 ++++----- .../01-recursion/01-sum-to/solution.md | 2 +- .../03-fibonacci-numbers/solution.md | 4 +- .../01-recursion/03-fibonacci-numbers/task.md | 2 +- .../04-output-single-linked-list/task.md | 4 +- .../solution.md | 4 +- .../task.md | 4 +- .../01-recursion/article.md | 58 +++---- .../02-rest-parameters-spread/article.md | 22 +-- .../4-counter-object-independent/task.md | 2 +- .../03-closure/9-sort-by-field/task.md | 4 +- .../03-closure/article.md | 50 +++--- 1-js/06-advanced-functions/04-var/article.md | 4 +- .../05-global-object/article.md | 32 ++-- .../5-sum-many-brackets/solution.md | 4 +- .../06-function-object/article.md | 30 ++-- .../07-new-function/article.md | 2 +- .../08-settimeout-setinterval/article.md | 20 +-- .../04-throttle/solution.md | 4 +- .../09-call-apply-decorators/article.md | 36 ++--- .../2-write-to-object-after-bind/solution.md | 2 +- .../2-write-to-object-after-bind/task.md | 2 +- .../10-bind/3-second-bind/solution.md | 4 +- .../10-bind/3-second-bind/task.md | 4 +- .../solution.md | 2 +- .../4-function-property-after-bind/task.md | 2 +- .../10-bind/5-question-use-bind/solution.md | 4 +- .../10-bind/6-ask-partial/task.md | 2 +- 1-js/06-advanced-functions/10-bind/article.md | 56 +++---- .../12-arrow-functions/article.md | 8 +- .../01-property-descriptors/article.md | 32 ++-- .../02-property-accessors/article.md | 20 +-- 1-js/07-object-properties/index.md | 4 +- .../1-property-after-delete/task.md | 2 +- .../2-search-algorithm/solution.md | 4 +- .../2-search-algorithm/task.md | 2 +- .../3-proto-and-this/solution.md | 2 +- .../3-proto-and-this/task.md | 4 +- .../4-hamster-proto/solution.md | 20 +-- .../4-hamster-proto/task.md | 6 +- .../01-prototype-inheritance/article.md | 70 ++++----- .../1-changing-prototype/solution.md | 8 +- .../1-changing-prototype/task.md | 2 +- .../4-new-object-same-constructor/solution.md | 12 +- .../4-new-object-same-constructor/task.md | 6 +- .../02-function-prototype/article.md | 30 ++-- .../2-defer-to-prototype-extended/solution.md | 4 +- .../03-native-prototypes/article.md | 44 +++--- .../2-dictionary-tostring/solution.md | 4 +- .../2-dictionary-tostring/task.md | 8 +- .../3-compare-calls/solution.md | 2 +- .../3-compare-calls/task.md | 2 +- .../04-prototype-methods/article.md | 68 ++++----- 1-js/09-classes/01-class/article.md | 42 +++--- .../1-class-constructor-error/task.md | 2 +- .../02-class-inheritance/article.md | 10 +- .../3-class-extend-object/task.md | 4 +- .../03-static-properties-methods/article.md | 14 +- .../article.md | 20 +-- 1-js/09-classes/05-extend-natives/article.md | 10 +- 1-js/09-classes/06-instanceof/article.md | 24 +-- 1-js/09-classes/07-mixins/article.md | 16 +- 1-js/10-error-handling/1-try-catch/article.md | 40 ++--- .../2-custom-errors/article.md | 20 +-- 1-js/11-async/02-promise-basics/article.md | 26 ++-- 1-js/11-async/03-promise-chaining/article.md | 18 +-- .../04-promise-error-handling/article.md | 8 +- 1-js/11-async/05-promise-api/article.md | 20 +-- 1-js/11-async/07-microtask-queue/article.md | 4 +- .../02-rewrite-async-2/solution.md | 6 +- .../08-async-await/02-rewrite-async-2/task.md | 6 +- .../03-async-from-regular/task.md | 2 +- 1-js/11-async/08-async-await/article.md | 6 +- .../1-generators/article.md | 36 ++--- .../2-async-iterators-generators/article.md | 32 ++-- 1-js/13-modules/01-modules-intro/article.md | 44 +++--- 1-js/13-modules/02-import-export/article.md | 20 +-- .../03-modules-dynamic-imports/article.md | 6 +- .../01-proxy/01-error-nonexisting/task.md | 2 +- .../01-proxy/03-observable/solution.md | 4 +- .../99-js-misc/01-proxy/03-observable/task.md | 4 +- 1-js/99-js-misc/01-proxy/article.md | 142 +++++++++--------- .../03-currying-partials/article.md | 4 +- 1-js/99-js-misc/04-reference-type/article.md | 14 +- 1-js/99-js-misc/06-unicode/article.md | 4 +- 159 files changed, 1317 insertions(+), 1317 deletions(-) diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md index e1639fef4..84e5164f1 100644 --- a/1-js/01-getting-started/1-intro/article.md +++ b/1-js/01-getting-started/1-intro/article.md @@ -1,6 +1,6 @@ # Вступ до JavaScript -Давайте розглянемо, що такого особливого в JavaScript, чого ми можемо досягти за її допомогою та які ще технології пов’язані з нею. +Давайте розглянемо, що такого особливого в JavaScript, чого ми можемо досягти за її допомогою та які ще технології пов'язані з нею. ## Що таке JavaScript? @@ -28,7 +28,7 @@ - [SpiderMonkey](https://uk.wikipedia.org/wiki/SpiderMonkey) -- в Firefox. - ...Є також інші кодові назви як "Chakra" для IE, "JavaScriptCore", "Nitro" і "SquirrelFish" для Safari, та інші. -Терміни вище добре було б запам’ятати, оскільки вони використовуються в статтях розробників на просторах інтернету. Ми також будемо їх використовувати. Наприклад, якщо "можливість X підтримується в V8", то, імовірно, вона працюватиме в Chrome, Opera та Edge. +Терміни вище добре було б запам'ятати, оскільки вони використовуються в статтях розробників на просторах інтернету. Ми також будемо їх використовувати. Наприклад, якщо "можливість X підтримується в V8", то, імовірно, вона працюватиме в Chrome, Opera та Edge. ```smart header="Як рушії працюють?" @@ -43,11 +43,11 @@ ## Що може вбудований у браузер JavaScript? -Сучасний JavaScript -- це "безпечна" мова програмування. Вона не надає низькорівневого доступу до пам’яті чи процесора, оскільки була створена для браузерів, які цього не потребують. +Сучасний JavaScript -- це "безпечна" мова програмування. Вона не надає низькорівневого доступу до пам'яті чи процесора, оскільки була створена для браузерів, які цього не потребують. Можливості JavaScript значно залежать від середовища, у якому виконується скрипт. Наприклад, [Node.js](https://uk.wikipedia.org/wiki/Node.js) підтримує функції, які дозволяють JavaScript читати/записувати довільні файли, здійснювати мережеві запити тощо. -Вбудована в браузер JavaScript може робити все, що пов’язано з управлінням вебсторінками, взаємодією з користувачем та вебсервером. +Вбудована в браузер JavaScript може робити все, що пов'язано з управлінням вебсторінками, взаємодією з користувачем та вебсервером. Наприклад, JavaScript може: @@ -55,11 +55,11 @@ - Реагувати на дії користувача, опрацьовувати натискання миші, переміщення вказівника, натискання на клавіші клавіатури. - Відправляти запити через мережу до віддалених серверів, завантажувати та відвантажувати файли (так звані технології [AJAX](https://uk.wikipedia.org/wiki/AJAX) і [COMET](https://uk.wikipedia.org/wiki/Comet_(програмування))). - Отримувати і надсилати [куки](https://uk.wikipedia.org/wiki/Куки), ставити запитання відвідувачам, показувати повідомлення. -- Запам’ятовувати дані на стороні клієнта ("[local storage](https://developer.mozilla.org/uk/docs/Web/API/Window/localStorage)"), які будуть доступні в майбутніх сесіях на цьому вебсайті. +- Запам'ятовувати дані на стороні клієнта ("[local storage](https://developer.mozilla.org/uk/docs/Web/API/Window/localStorage)"), які будуть доступні в майбутніх сесіях на цьому вебсайті. ## Що НЕ може JavaScript? -Можливості JavaScript у браузері обмежені для безпеки користувача. Мета полягає в тому, щоб небезпечні вебсторінки не мали доступу до приватної інформації та не могли пошкодити інформацію на комп’ютері користувача. +Можливості JavaScript у браузері обмежені для безпеки користувача. Мета полягає в тому, щоб небезпечні вебсторінки не мали доступу до приватної інформації та не могли пошкодити інформацію на комп'ютері користувача. Приклади таких обмежень: @@ -100,7 +100,7 @@ JavaScript -- це єдина браузерна технологія, яка с Цього слід очікувати, тому що проєкти та вимоги різні для кожного. -Останнім часом з’явилося безліч нових мов, які *транспілюються* (конвертуються) в JavaScript перед виконанням у браузері. +Останнім часом з'явилося безліч нових мов, які *транспілюються* (конвертуються) в JavaScript перед виконанням у браузері. Сучасні інструменти роблять транспіляцію дуже швидкою та прозорою, дозволяючи розробникам писати код іншою мовою й автоматично конвертувати його "під капотом". diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md index 5747a8f90..5573ff78f 100644 --- a/1-js/01-getting-started/4-devtools/article.md +++ b/1-js/01-getting-started/4-devtools/article.md @@ -53,7 +53,7 @@ Safari (стандартний браузер у macOS, не підтримує ![safari](safari.png) -Тепер комбінація клавіш `key:Cmd+Opt+C` може переключати консоль. Також зауважте, що з’явився новий пункт "Розробка" у верхньому меню. Це меню має багато команд та опцій. +Тепер комбінація клавіш `key:Cmd+Opt+C` може переключати консоль. Також зауважте, що з'явився новий пункт "Розробка" у верхньому меню. Це меню має багато команд та опцій. ## Підсумки diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md index 37a05a35d..cfaf136cb 100644 --- a/1-js/02-first-steps/02-structure/article.md +++ b/1-js/02-first-steps/02-structure/article.md @@ -61,7 +61,7 @@ alert("Привіт"); [1, 2].forEach(alert); ``` -Поки що не задумуйтеся, що означають квадратні дужки `[]` і `forEach`. Ми вивчимо їх пізніше. Зараз просто запам’ятайте результат виконання коду: спочатку виведеться `Привіт`, далі `1`, а потім `2`. +Поки що не задумуйтеся, що означають квадратні дужки `[]` і `forEach`. Ми вивчимо їх пізніше. Зараз просто запам'ятайте результат виконання коду: спочатку виведеться `Привіт`, далі `1`, а потім `2`. А тепер видалимо крапку з комою після першого `alert`: @@ -83,7 +83,7 @@ alert("Привіт") alert("Привіт")[1, 2].forEach(alert); ``` -Виглядає дивно, чи не так? У цьому випадку таке об’єднання неправильне. Щоби код правильно працював, нам потрібно поставити крапку з комою після `alert`. +Виглядає дивно, чи не так? У цьому випадку таке об'єднання неправильне. Щоби код правильно працював, нам потрібно поставити крапку з комою після `alert`. Це може статися в інших випадках. ```` diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md index b6cff1ea7..aa7ac1e19 100644 --- a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md +++ b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md @@ -6,15 +6,15 @@ let ourPlanetName = "Земля"; ``` -Зверніть увагу, ми могли використати коротше ім’я `planet`, але тоді буде незрозуміло, яку планету ми маємо на увазі. Краще описати вміст змінної детальніше. Принаймні до тих пір, поки ім’я змінної неСтанеЗанадтоДовгим. +Зверніть увагу, ми могли використати коротше ім'я `planet`, але тоді буде незрозуміло, яку планету ми маємо на увазі. Краще описати вміст змінної детальніше. Принаймні до тих пір, поки ім'я змінної неСтанеЗанадтоДовгим. -## Ім’я поточного відвідувача +## Ім'я поточного відвідувача ```js let currentUserName = "Іван"; ``` -Знову ж таки, ми можемо скоротити ім’я до `userName`, якщо ми точно знатимемо, що це поточний відвідувач. +Знову ж таки, ми можемо скоротити ім'я до `userName`, якщо ми точно знатимемо, що це поточний відвідувач. Сучасні редактори й автодоповнювачі дозволяють легко писати довгі імена змінних. Не економте букв. Імена з трьох слів цілком нормальні. diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 74c8fe9cf..e0edc6360 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -162,7 +162,7 @@ let message = "Той"; // SyntaxError: 'message' has already been declared В JavaScript є два обмеження, які стосуються імен змінних: -1. Ім’я має містити лише букви, цифри або символи `$` і `_`. +1. Ім'я має містити лише букви, цифри або символи `$` і `_`. 2. Перший символ не має бути числом. Ось приклади допустимих імен: @@ -265,7 +265,7 @@ myBirthday = '01.01.2001'; // помилка, не можна перевизна ### Константи в верхньому регістрі -Широко поширена практика використання констант як псевдонімів для значень, які важко запам’ятати і які відомі до початку виконання скрипта. +Широко поширена практика використання констант як псевдонімів для значень, які важко запам'ятати і які відомі до початку виконання скрипта. Такі константи пишуться в верхньому регістрі з використанням підкреслень. @@ -284,7 +284,7 @@ alert(color); // #FF7F00 Переваги: -- `COLOR_ORANGE` набагато легше запам’ятати, ніж `"#FF7F00"`. +- `COLOR_ORANGE` набагато легше запам'ятати, ніж `"#FF7F00"`. - Набагато легше допустити помилку в `"#FF7F00"`, ніж під час введення `COLOR_ORANGE`. - Під час читання коду `COLOR_ORANGE` набагато зрозуміліше, ніж `#FF7F00`. diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md index 915763e77..bfd1109a2 100644 --- a/1-js/02-first-steps/05-types/article.md +++ b/1-js/02-first-steps/05-types/article.md @@ -12,7 +12,7 @@ let message = "привіт"; message = 123456; ``` -Мови програмування, які дають змогу таке робити, називаються "динамічно типізованими". Мається на увазі, що типи даних визначені, але змінні не прив’язанні до жодного типу. +Мови програмування, які дають змогу таке робити, називаються "динамічно типізованими". Мається на увазі, що типи даних визначені, але змінні не прив'язанні до жодного типу. ## Число (number) @@ -68,7 +68,7 @@ n = 12.345; ## BigInt [#bigint-type] -У JavaScript, тип "number" не може містити числа більші за (253-1) (це `9007199254740991`), або менші за -(253-1) для від’ємних чисел. +У JavaScript, тип "number" не може містити числа більші за (253-1) (це `9007199254740991`), або менші за -(253-1) для від'ємних чисел. Якщо бути дійсно точним, тип "number" може зберігати більші цілі числа (до 1,7976931348623157 * 10308), але поза межами безпечного діапазону цілих чисел ±(2 53-1) виникне помилка точності, оскільки не всі цифри вміщуються у фіксованому 64-бітному сховищі. Тому може бути збережено "приблизне" значення. @@ -155,7 +155,7 @@ alert("результат: ${1 + 2}"); // результат: ${1 + 2} (подв Наприклад: ```js -let nameFieldChecked = true; // так, ім’я було перевірене +let nameFieldChecked = true; // так, ім'я було перевірене let ageFieldChecked = false; // ні, вік не був перевіреним ``` @@ -179,7 +179,7 @@ alert(isGreater); // true (результат порівняння — "так") let age = null; ``` -В JavaScript `null` не є "посиланням на неіснуючий об’єкт" або "покажчиком на null", як може бути в інших мовах програмування. +В JavaScript `null` не є "посиланням на неіснуючий об'єкт" або "покажчиком на null", як може бути в інших мовах програмування. Це лише спеціальне значення, яке представляє "нічого", "порожнє" або "невідоме значення". @@ -212,15 +212,15 @@ alert(age); // "undefined" ...Але ми не рекомендуємо так робити. Як правило, ми використовуємо `null`, щоби присвоїти змінній значення "порожнє" або "невідоме", тоді як `undefined` зарезервоване для позначення початкового значення для неприсвоєних речей. -## Об’єкти (object) та символи (symbol) +## Об'єкти (object) та символи (symbol) Тип `object` є особливим типом. -Усі інші типи називаються "примітивами", тому що їхні значення можуть містити тільки один елемент (це може бути рядок, число, або будь-що інше). В об’єктах же зберігаються колекції даних і більш складні структури. +Усі інші типи називаються "примітивами", тому що їхні значення можуть містити тільки один елемент (це може бути рядок, число, або будь-що інше). В об'єктах же зберігаються колекції даних і більш складні структури. -Об’єкти є важливою частиною мови, тому ми окремо розглянемо їх у розділі після того, як дізнаємося більше про примітиви. +Об'єкти є важливою частиною мови, тому ми окремо розглянемо їх у розділі після того, як дізнаємося більше про примітиви. -Тип `symbol` використовується для створення унікальних ідентифікаторів в об’єктах. Ми згадали цей тип для повноти, проте докладніше вивчимо його після об’єктів. +Тип `symbol` використовується для створення унікальних ідентифікаторів в об'єктах. Ми згадали цей тип для повноти, проте докладніше вивчимо його після об'єктів. ## Оператор typeof [#type-typeof] @@ -256,9 +256,9 @@ typeof alert // "function" (3) Останні три рядки можуть потребувати додаткового пояснення: -1. `Math` — це вбудований об’єкт, який забезпечує математичні операції. Ми вивчимо його в розділі . Тут він використаний лише як приклад об’єкта. -2. Результатом `typeof null` є `"object"`. Це офіційно визнана помилка поведінки `typeof`, що є ще з ранніх днів JavaScript і зберігається для сумісності. Безперечно, `null` не є об’єктом. Це особливе значення з власним типом. У цьому разі поведінка `typeof` некоректна. -3. Результатом `typeof alert` є `"function"`, тому що `alert` — це функція. Ми будемо вивчати функції в наступних розділах, де ми також побачимо, що в JavaScript немає спеціального типу "function". Функції належать до типу "об’єкт". Але `typeof` трактує їх по-іншому, повертаючи `"function"`. Це також присутнє з ранніх днів JavaScript. Технічно, така поведінка не зовсім правильна, але може бути зручною на практиці. +1. `Math` — це вбудований об'єкт, який забезпечує математичні операції. Ми вивчимо його в розділі . Тут він використаний лише як приклад об'єкта. +2. Результатом `typeof null` є `"object"`. Це офіційно визнана помилка поведінки `typeof`, що є ще з ранніх днів JavaScript і зберігається для сумісності. Безперечно, `null` не є об'єктом. Це особливе значення з власним типом. У цьому разі поведінка `typeof` некоректна. +3. Результатом `typeof alert` є `"function"`, тому що `alert` — це функція. Ми будемо вивчати функції в наступних розділах, де ми також побачимо, що в JavaScript немає спеціального типу "function". Функції належать до типу "об'єкт". Але `typeof` трактує їх по-іншому, повертаючи `"function"`. Це також присутнє з ранніх днів JavaScript. Технічно, така поведінка не зовсім правильна, але може бути зручною на практиці. ```smart header="Синтаксис `typeof(x)`" Можливо ви зустрічали інший синтаксис: `typeof(x)`. Це те саме, що `typeof x`. @@ -290,6 +290,6 @@ typeof alert // "function" (3) - Зазвичай використовують синтаксис `typeof x`, проте `typeof(x)` також можливий. - Повертає рядок із назвою типу, як-от `"string"`. -- Для `null` повертає `"object"` —- це помилка в мові, `null` насправді не об’єкт. +- Для `null` повертає `"object"` —- це помилка в мові, `null` насправді не об'єкт. -У наступних розділах ми зосередимося на примітивних значеннях, а коли ознайомимося з ними, то перейдемо до об’єктів. +У наступних розділах ми зосередимося на примітивних значеннях, а коли ознайомимося з ними, то перейдемо до об'єктів. diff --git a/1-js/02-first-steps/06-alert-prompt-confirm/article.md b/1-js/02-first-steps/06-alert-prompt-confirm/article.md index dfd9377cb..b8fbafb24 100644 --- a/1-js/02-first-steps/06-alert-prompt-confirm/article.md +++ b/1-js/02-first-steps/06-alert-prompt-confirm/article.md @@ -97,7 +97,7 @@ alert( isBoss ); // true, якщо натиснута OK Усі ці методи є модальними: вони призупиняють виконання скриптів та не дають відвідувачам змогу взаємодіяти з рештою сторінки, поки вікно не буде закрите. -Є два обмеження, пов’язані з усіма методами вище: +Є два обмеження, пов'язані з усіма методами вище: 1. Точне розташування модального вікна визначається браузером. Зазвичай це в центрі. 2. Точний вигляд вікна також залежить від браузера. Ми не можемо його змінити. diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md index 324413407..2b0f8e526 100644 --- a/1-js/02-first-steps/07-type-conversions/article.md +++ b/1-js/02-first-steps/07-type-conversions/article.md @@ -6,10 +6,10 @@ Є також випадки, коли нам необхідно явно перетворити значення на очікуваний тип. -```smart header="Поки що не говоримо про об’єкти" -У цьому розділі ми не будемо охоплювати об’єкти. Поки що ми поговоримо тільки про примітиви. +```smart header="Поки що не говоримо про об'єкти" +У цьому розділі ми не будемо охоплювати об'єкти. Поки що ми поговоримо тільки про примітиви. -Пізніше, після ознайомлення з об’єктами, ми розглянемо їхнє перетворення в розділі . +Пізніше, після ознайомлення з об'єктами, ми розглянемо їхнє перетворення в розділі . ``` ## Перетворення на рядок @@ -142,7 +142,7 @@ alert( Boolean(" ") ); // пробіли, також true (будь-які не |будь-які інші значення| `true` | -Більшість із цих правил легко зрозуміти й запам’ятати. Примітними винятками, де люди зазвичай роблять помилки, є: +Більшість із цих правил легко зрозуміти й запам'ятати. Примітними винятками, де люди зазвичай роблять помилки, є: - `undefined` є `NaN` як число, а не `0`. - `"0"` і рядки, що мають тільки пробіли, такі як `" "`, є `true` як булеві значення. diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md index f24baf220..6afecf7d7 100644 --- a/1-js/02-first-steps/08-operators/article.md +++ b/1-js/02-first-steps/08-operators/article.md @@ -43,7 +43,7 @@ JavaScript підтримує такі математичні операції: ### Остача від ділення % -Оператор остачі `%`, попри свій зовнішній вигляд, не пов’язаний із відсотками. +Оператор остачі `%`, попри свій зовнішній вигляд, не пов'язаний із відсотками. Результатом `a % b` є [остача](https://uk.wikipedia.org/wiki/Остача) цілочислового ділення `a` на `b`. @@ -79,13 +79,13 @@ alert( 8 ** (1/3) ); // 2 (степінь 1/3 — це теж саме, що к ``` -## Об’єднання рядків через бінарний + +## Об'єднання рядків через бінарний + Розглянемо особливості операторів JavaScript, які виходять за межі шкільної арифметики. Зазвичай оператор плюс `+` додає числа. -Але якщо бінарний `+` застосовується до рядків, він об’єднує їх: +Але якщо бінарний `+` застосовується до рядків, він об'єднує їх: ```js let s = 'мій_' + 'рядок'; @@ -109,7 +109,7 @@ alert( 2 + '1' ); // "21" alert(2 + 2 + '1' ); // "41", а не "221" ``` -Тут оператори виконуються один за одним. Перший `+` додає два числа, тому він поверне `4`; а наступний оператор `+` вже додасть (об’єднає) попередній результат із рядком `1`. У підсумку ми отримаємо рядок `'41'` (`4 + '1'`). +Тут оператори виконуються один за одним. Перший `+` додає два числа, тому він поверне `4`; а наступний оператор `+` вже додасть (об'єднає) попередній результат із рядком `1`. У підсумку ми отримаємо рядок `'41'` (`4 + '1'`). ```js run alert('1' + 2 + 2); // "122", а не "14" @@ -158,7 +158,7 @@ alert( +"" ); // 0 let apples = "2"; let oranges = "3"; -alert( apples + oranges ); // "23", бінарний плюс об’єднує рядки +alert( apples + oranges ); // "23", бінарний плюс об'єднує рядки ``` Якщо ми хочемо використовувати їх як числа, нам потрібно конвертувати, а потім підсумувати їх: @@ -178,7 +178,7 @@ alert( +apples + +oranges ); // 5 З погляду математика надмірні плюси можуть здатися дивними. Але з погляду програміста тут немає нічого особливого: спочатку застосовуються унарні плюси, вони перетворюють рядки на числа, а потім бінарний плюс підсумовує їх. -Чому унарні плюси застосовуються до значень перед бінарними плюсами? Як ми побачимо далі, це пов’язано з їхнім *вищим пріоритетом*. +Чому унарні плюси застосовуються до значень перед бінарними плюсами? Як ми побачимо далі, це пов'язано з їхнім *вищим пріоритетом*. ## Пріоритет оператора @@ -190,9 +190,9 @@ alert( +apples + +oranges ); // 5 У JavaScript є багато операторів. Кожен оператор має відповідний номер пріоритету. Першим виконується той оператор, який має найбільший номер пріоритету. Якщо пріоритет є однаковим, порядок виконання — зліва направо. -Ось витяг із [таблиці пріоритетів](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (вам не потрібно її запам’ятовувати, але зверніть увагу, що унарні оператори мають вищий пріоритет за відповідні бінарні): +Ось витяг із [таблиці пріоритетів](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (вам не потрібно її запам'ятовувати, але зверніть увагу, що унарні оператори мають вищий пріоритет за відповідні бінарні): -| Пріоритет | Ім’я | Знак | +| Пріоритет | Ім'я | Знак | |------------|------|------| | ... | ... | ... | | 14 | унарний плюс | `+` | diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md index 9032c192f..5107c973c 100644 --- a/1-js/02-first-steps/09-comparison/article.md +++ b/1-js/02-first-steps/09-comparison/article.md @@ -202,7 +202,7 @@ alert( undefined == 0 ); // false (3) ### Як уникати проблем -Чому ми переглядали ці приклади? Чи повинні ми постійно пам’ятати про всі ці особливості? Не обов’язково. З часом всі ці заплутані правила стануть для вас знайомими, але можна уникнути проблем, якщо дотримуватися надійних правил: +Чому ми переглядали ці приклади? Чи повинні ми постійно пам'ятати про всі ці особливості? Не обов'язково. З часом всі ці заплутані правила стануть для вас знайомими, але можна уникнути проблем, якщо дотримуватися надійних правил: - Будьте пильні під час порівняння будь-якого значення з `undefined/null`, за винятком строгого порівняння `===`. - Не використовуйте порівняння `>= > < <=` зі змінними, які можуть приймати значення `null/undefined`, хіба що ви цілком впевнені в тому, що робите. Якщо змінна може приймати ці значення, то додайте для них окремі перевірки. diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md index 2f8c85628..ec91e5a5a 100644 --- a/1-js/02-first-steps/10-ifelse/article.md +++ b/1-js/02-first-steps/10-ifelse/article.md @@ -68,7 +68,7 @@ if (condition) { ## Блок "else" -Вираз `if` може містити необов’язковий блок `else` ("інакше"). Він виконується, коли умова є хибною. +Вираз `if` може містити необов'язковий блок `else` ("інакше"). Він виконується, коли умова є хибною. Наприклад: ```js run @@ -101,7 +101,7 @@ if (year < 2015) { У наведеному вище коді JavaScript спочатку перевіряє `year < 2015`. Якщо це не вірно, перевіряється наступна умова `year > 2015`. Якщо це також неправда, показується останній `alert`. -Може бути більше `else if` блоків. Останній блок `else` є необов’язковим. +Може бути більше `else if` блоків. Останній блок `else` є необов'язковим. ## Умовний оператор '?' diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 968267399..a90d30249 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -1,6 +1,6 @@ # Логічні оператори -В JavaScript існує чотири логічні оператори: `||` (АБО), `&&` (І), `!` (НЕ), `??` (оператор null-об’єднання). В цьому розділі ми розглянемо перші три оператори, а оператор `??` — в наступному розділі. +В JavaScript існує чотири логічні оператори: `||` (АБО), `&&` (І), `!` (НЕ), `??` (оператор null-об'єднання). В цьому розділі ми розглянемо перші три оператори, а оператор `??` — в наступному розділі. Хоча вони називаються "логічними", вони можуть бути застосовані до значень будь-якого типу, не тільки булевих. Їх результати також можуть бути будь-якого типу. @@ -101,7 +101,7 @@ alert( undefined || null || 0 ); // 0 (усі хибні, повертаєтьс 1. **Отримання першого істинного значення зі списку змінних або виразів.** - Наприклад, маємо змінні `firstName`, `lastName` та `nickName`, усі необов’язкові (тобто вони можуть бути невизначеними або мати хибні значення). + Наприклад, маємо змінні `firstName`, `lastName` та `nickName`, усі необов'язкові (тобто вони можуть бути невизначеними або мати хибні значення). Використаємо АБО `||`, щоб вибрати ту змінну, яка має дані, і виведемо її (або рядок `"Анонім"`, якщо жодна змінна не має даних): @@ -175,7 +175,7 @@ if (1 && 0) { // обчислюється як true && false ## І "&&" шукає перше хибне значення -Дано декілька значень, об’єднаних кількома І: +Дано декілька значень, об'єднаних кількома І: ```js result = value1 && value2 && value3; diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md index 1f8157ed6..53e7c7582 100644 --- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md +++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md @@ -1,8 +1,8 @@ -# Оператор об’єднання з null '??' +# Оператор об'єднання з null '??' [recent browser="new"] -Оператор об’єднання з null записується як два знаки питання `??`. +Оператор об'єднання з null записується як два знаки питання `??`. Оскільки `null` і `undefined` сприймаються однаково, ми введемо спеціальну домовленність. В цій статті ми будемо вважати, що значення виразу "визначене", якщо воно відрізняється від `null` та `undefined`. @@ -12,7 +12,7 @@ Інакше кажучи, `??` повертає перший аргумент, якщо він не `null/undefined`. Інакше, другий. -Оператор об’єднання з null не є абсолютно новим. Це просто хороший синтаксис, щоб отримати перше "визначене" значення з двох. +Оператор об'єднання з null не є абсолютно новим. Це просто хороший синтаксис, щоб отримати перше "визначене" значення з двох. Ми можемо переписати вираз `result = a ?? b`, використовуючи оператори, які ми вже знаємо: @@ -26,7 +26,7 @@ result = (a !== null && a !== undefined) ? a : b; Наприклад, тут ми показуємо значення у змінній `user`, якщо її значення не `null/undefined`, інакше -- показуємо `Анонімний`: -Ось приклад з `user`, якому не присвоєне ім’я: +Ось приклад з `user`, якому не присвоєне ім'я: ```js run let user; @@ -38,7 +38,7 @@ alert(user ?? "Анонімний"); // Анонімний (user є undefined) Скажімо, у нас є дані користувача в змінних `firstName`, `lastName` або `nickName`. Всі вони можуть бути не визначені, якщо користувач вирішив не вводити значення. -Ми хотіли б показати ім’я користувача, використовуючи одну з цих змінних, або показати "Анонімний", якщо всі вони `null/undefined`. +Ми хотіли б показати ім'я користувача, використовуючи одну з цих змінних, або показати "Анонімний", якщо всі вони `null/undefined`. Використаймо оператор `??` для цього: @@ -72,7 +72,7 @@ alert(firstName || lastName || nickName || "Анонімний"); // Супер Історично, оператор АБО `||` був першим. Він існує з початку JavaScript, тому розробники використовували його для цих цілей протягом тривалого часу. -З іншого боку, оператор об’єднання з null `??` було нещодавно додано в JavaScript, і причиною того було те, що люди були не дуже задоволені `||`. +З іншого боку, оператор об'єднання з null `??` було нещодавно додано в JavaScript, і причиною того було те, що люди були не дуже задоволені `||`. Важлива різниця між ними полягає в тому, що: - `||` повертає перше *істинне* значення. @@ -102,7 +102,7 @@ alert(height ?? 100); // 0 Пріоритет оператора `??` такий самий, як у `||`. Він дорівнює `3` у [таблиці MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). -Це означає, що, як і `||`, оператор об’єднання з null `??` оцінюється до `=` та `?`, але після більшості інших операцій, таких як `+`, `*`. +Це означає, що, як і `||`, оператор об'єднання з null `??` оцінюється до `=` та `?`, але після більшості інших операцій, таких як `+`, `*`. ``` js let height = null; @@ -148,7 +148,7 @@ alert(x); // 2 ## Підсумки -- Оператор об’єднання з null `??` надає короткий спосіб вибору першого "визначеного" значення зі списку. +- Оператор об'єднання з null `??` надає короткий спосіб вибору першого "визначеного" значення зі списку. Він використовується для присвоєння типових значень до змінних: diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md index e0c195fa8..b2b9cc338 100644 --- a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md +++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md @@ -8,6 +8,6 @@ importance: 5 Цикл повинен запитувати число доти, доки відвідувач не введе число, більше за `100`, або не скасує ввід/введе порожній рядок. -Ми припускаємо, що відвідувач вводитиме лише числа. В цьому завданні не обов’язково реалізовувати оброблення не-числового введення. +Ми припускаємо, що відвідувач вводитиме лише числа. В цьому завданні не обов'язково реалізовувати оброблення не-числового введення. [demo] diff --git a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md index 4d3cf8423..a911d0733 100644 --- a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md +++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md @@ -14,4 +14,4 @@ function checkAge(age) { } ``` -Зверніть увагу, що круглі дужки навколо `age > 18` не обов’язкові. Вони тут для кращої читабельності коду. +Зверніть увагу, що круглі дужки навколо `age > 18` не обов'язкові. Вони тут для кращої читабельності коду. diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md index d4c3147ff..b9bdfcc92 100644 --- a/1-js/02-first-steps/15-function-basics/article.md +++ b/1-js/02-first-steps/15-function-basics/article.md @@ -20,7 +20,7 @@ function showMessage() { } ``` -Спочатку ми пишемо `function` — це ключове слово (keyword), яке дає зрозуміти комп’ютеру, що далі буде оголошення функції. Потім — *назву функції* і список її *параметрів* в дужках (розділені комою). Якщо параметрів немає, ми залишаємо *пусті дужки*. І нарешті, код функції, який також називають *тілом функції* між фігурними дужками. +Спочатку ми пишемо `function` — це ключове слово (keyword), яке дає зрозуміти комп'ютеру, що далі буде оголошення функції. Потім — *назву функції* і список її *параметрів* в дужках (розділені комою). Якщо параметрів немає, ми залишаємо *пусті дужки*. І нарешті, код функції, який також називають *тілом функції* між фігурними дужками. ```js function name(parameter1, parameter2, ... parameterN) { @@ -28,7 +28,7 @@ function name(parameter1, parameter2, ... parameterN) { } ``` -Нашу нову функцію можна викликати, написавши її ім’я і дужки: `showMessage()`. +Нашу нову функцію можна викликати, написавши її ім'я і дужки: `showMessage()`. Наприклад: @@ -107,7 +107,7 @@ alert( userName ); // *!*Богдан*/!*, значення було зміне Зовнішня змінна використовується тоді, коли немає локальної. -Якщо всередині функції є змінна з таким самим ім’ям, то вона *перекриває* зовнішню. Наприклад, наступний код використовує локальну змінну `userName`. Зовнішня ігнорується. +Якщо всередині функції є змінна з таким самим ім'ям, то вона *перекриває* зовнішню. Наприклад, наступний код використовує локальну змінну `userName`. Зовнішня ігнорується. ```js run let userName = 'Іван'; // оголошення зовнішньої змінної @@ -418,9 +418,9 @@ return ( ## Найменування функції [#function-naming] -Функції виконують дії. Тому в їхніх іменах зазвичай використовують дієслова. Ім’я повинне бути лаконічним, повинне якнайточніше описувати, що робить функція, щоб кожен хто читає код зміг зрозуміти, що саме робить функція. +Функції виконують дії. Тому в їхніх іменах зазвичай використовують дієслова. Ім'я повинне бути лаконічним, повинне якнайточніше описувати, що робить функція, щоб кожен хто читає код зміг зрозуміти, що саме робить функція. -Поширена практика розпочинати ім’я функції зі словесного префіксу, який описує дію. В команді має бути домовленість щодо значення префіксів. +Поширена практика розпочинати ім'я функції зі словесного префіксу, який описує дію. В команді має бути домовленість щодо значення префіксів. Наприклад, функції, які починаються з префіксу `"show"` зазвичай щось показують. @@ -441,7 +441,7 @@ createForm(..) // створює форму (і зазвичай її по checkPermission(..) // перевіряє доступ, повертає true/false ``` -Якщо є префікси, погляд на ім’я функції дає зрозуміти, яку роботу вона виконує і яке значення повертає. +Якщо є префікси, погляд на ім'я функції дає зрозуміти, яку роботу вона виконує і яке значення повертає. ```smart header="Одна функція -- одна дія" Функція повинна робити саме те, що написано в її імені, не більше. @@ -517,7 +517,7 @@ function isPrime(n) { Оголошення функції виглядає ось так: ```js -function ім’я(параметри, розділені, комою) { +function ім'я(параметри, розділені, комою) { /* тіло, код функції */ } ``` @@ -532,8 +532,8 @@ function ім’я(параметри, розділені, комою) { Найменування функцій: -- Ім’я функції повинне бути коротким і чітко відображати, що робить функція. Побачивши виклик функції в коді, ви повинні зразу зрозуміти, що функція робить, і що повертає. -- Функція -- це дія, тому її ім’я зазвичай складається з дієслова. +- Ім'я функції повинне бути коротким і чітко відображати, що робить функція. Побачивши виклик функції в коді, ви повинні зразу зрозуміти, що функція робить, і що повертає. +- Функція -- це дія, тому її ім'я зазвичай складається з дієслова. - Є багато загальноприйнятих префіксів, такі як `create…`, `show…`, `get…`, `check…` тощо. Використовуйте їх щоб пояснити, що робить функція. Функції -- це основні будівельні блоки скриптів. Ми розглянули лише основи функцій в JavaScript, проте вже зараз цього достатньо, щоб почати їх створювати і використовувати. Це лише початок шляху. Ми будемо неодноразово повертатися до функцій і вивчатимо їх все глибше і глибше. diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md index 4769e58e1..12a2d8b09 100644 --- a/1-js/02-first-steps/18-javascript-specials/article.md +++ b/1-js/02-first-steps/18-javascript-specials/article.md @@ -31,7 +31,7 @@ alert("Після цього повідомлення буде помилка") ```js function f() { - // після оголошення функції не обов’язково ставити крапку з комою + // після оголошення функції не обов'язково ставити крапку з комою } for(;;) { @@ -69,7 +69,7 @@ for(;;) { - `const` (константа, не можна змінювати) - `var` (старий спосіб, ми переглянемо його пізніше) -Ім’я змінної може включати: +Ім'я змінної може включати: - Літери і цифри; першим символом має бути лише літера, не цифра. - Допускаються символи `$` та `_`, в парі з літерами. - Не латинські символи, як кирилиця та ієрогліфи також допускаються, але вони не мають широкого вжитку. @@ -89,7 +89,7 @@ x = "Іван"; // тип змінився на "рядок" - булевий тип (`boolean`) для логічних значень: `true/false`, - `null` — тип з єдиним значенням `null`, який означає "пусто" або "не існує", - `undefined` — тип з єдиним значенням `undefined`, який означає "не присвоєно", -- об’єкт (`object`) та символ (`symbol`) — для складних структур даних та унікальних ідентифікаторів, ми їх ще не вивчили. +- об'єкт (`object`) та символ (`symbol`) — для складних структур даних та унікальних ідентифікаторів, ми їх ще не вивчили. Оператор `typeof` повертає тип змінної, за винятком двох випадків: ```js @@ -117,7 +117,7 @@ typeof function(){} == "function" // спеціально для функцій Наприклад: ```js run -let userName = prompt("Ваше ім’я?", "Настя"); +let userName = prompt("Ваше ім'я?", "Настя"); let isBunWanted = confirm("Хочете булочку?"); alert( "Відвідувач: " + userName ); // Настя @@ -133,7 +133,7 @@ JavaScript підтримує такі оператори: Арифметичні : Звичайні: `* + - /`, а також оператори `%`, для визначення остачі від ділення та `**` для піднесення до степеня. - Бінарний плюс `+` об’єднує (конкатинує) рядки. А якщо одним із операндів буде рядок, то інший операнд також буде конвертовано в рядок: + Бінарний плюс `+` об'єднує (конкатинує) рядки. А якщо одним із операндів буде рядок, то інший операнд також буде конвертовано в рядок: ```js run alert( '1' + 2 ); // '12', рядок @@ -150,9 +150,9 @@ JavaScript підтримує такі оператори: : Єдиний оператор з трьома параметрами: `cond ? resultA : resultB`. Якщо `cond` вірно, повертається `resultA`, інакше – `resultB`. Логічні оператори -: Логічні І `&&` та АБО `||` використовують так звані "ледачі обчислення" і насамкінець повертають значення, на якому воно зупинилося (не обов’язково `true` або `false`). Логічне НЕ `!` конвертує операнд в логічний тип і повертає інвертоване значення. +: Логічні І `&&` та АБО `||` використовують так звані "ледачі обчислення" і насамкінець повертають значення, на якому воно зупинилося (не обов'язково `true` або `false`). Логічне НЕ `!` конвертує операнд в логічний тип і повертає інвертоване значення. -Оператор об’єднання з null +Оператор об'єднання з null : Оператор `??` дає можливість вибору визначеного значення зі списку змінних. Результатом `a ?? b` буде `a` якщо його значення відмінне від `null/undefined`, інакше `b`. Порівнювання @@ -202,7 +202,7 @@ JavaScript підтримує такі оператори: Детальніше: . -Пізніше ми вивчимо більше видів циклів, які працюють з об’єктами. +Пізніше ми вивчимо більше видів циклів, які працюють з об'єктами. ## Конструкція "switch" diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md index b61411861..a7cf78377 100644 --- a/1-js/03-code-quality/01-debugging-chrome/article.md +++ b/1-js/03-code-quality/01-debugging-chrome/article.md @@ -127,7 +127,7 @@ function hello(name) { ![](chrome-sources-debugger-trace-1.svg) - Виконання коду відновилося, дійшло до іншої точки зупинки, всередині `say()` і налагоджувач знову (тимчасово) зупинив виконання. Зверніть увагу на вкладку "Call Stack" праворуч: в списку з’явився ще один виклик. Ми тепер всередині функції `say()`. + Виконання коду відновилося, дійшло до іншої точки зупинки, всередині `say()` і налагоджувач знову (тимчасово) зупинив виконання. Зверніть увагу на вкладку "Call Stack" праворуч: в списку з'явився ще один виклик. Ми тепер всередині функції `say()`.  — "Step": виконати наступну команду. Швидка клавіша: `key:F9`. : Якщо ми натиснемо на неї – виконається функція `alert`. diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md index eec5e67ce..479e100da 100644 --- a/1-js/03-code-quality/04-ninja-code/article.md +++ b/1-js/03-code-quality/04-ninja-code/article.md @@ -40,7 +40,7 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0; ```quote author="Лао-цзи (Дао де цзін)" Дао безсловесне. -Ім’я, яке можна назвати, не є постійним ім’ям. +Ім'я, яке можна назвати, не є постійним ім'ям. ``` Ще один спосіб писати стислий код -- використовувати однолітерні змінні. Наприклад: `a`, `b` або `c`. @@ -73,19 +73,19 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0; Великий образ неозорий. ``` -Обираючи ім’я, намагайтесь використовувати найбільш абстрактне слово. Прикладом може бути `obj`, `data`, `value`, `item`, `elem` тощо. +Обираючи ім'я, намагайтесь використовувати найбільш абстрактне слово. Прикладом може бути `obj`, `data`, `value`, `item`, `elem` тощо. - **`data` є ідеальним варіантом для імені змінної.** Використовуйте його всюди, де можете. І справді, кожна змінна має *дані*, вірно? - А що робити, якщо ім’я `data` вже зайняте? Спробуйте `value` -- воно також універсальне. Врешті-решт, кожна змінна набуває якесь *значення*. + А що робити, якщо ім'я `data` вже зайняте? Спробуйте `value` -- воно також універсальне. Врешті-решт, кожна змінна набуває якесь *значення*. -- **Добирайте ім’я змінним згідно з їхнім типом: `str`, `num`...** +- **Добирайте ім'я змінним згідно з їхнім типом: `str`, `num`...** Спробуйте. Той, що щойно став на шлях ніндзя, може засумніватися чи дійсно такі імена корисні. Авжеж! - Так, ім’я змінної дещо означає. Це допомагає зрозуміти, що ми використовуємо: рядок, число, чи щось ще. Проте коли сторонні люди намагатимуться зрозуміти код, вони будуть здивовані, що інформація про те, що саме містить змінна, відсутня. У результаті вони не зможуть змінити ваш добре обміркований код. + Так, ім'я змінної дещо означає. Це допомагає зрозуміти, що ми використовуємо: рядок, число, чи щось ще. Проте коли сторонні люди намагатимуться зрозуміти код, вони будуть здивовані, що інформація про те, що саме містить змінна, відсутня. У результаті вони не зможуть змінити ваш добре обміркований код. - Тип змінної досить легко знайти під час налаштування. Але що означає її ім’я? Який саме рядок/число вона зберігає? + Тип змінної досить легко знайти під час налаштування. Але що означає її ім'я? Який саме рядок/число вона зберігає? Жодного шансу дізнатися про це без тривалої медитації! @@ -105,12 +105,12 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0; ## Хитромудрі синоніми ```quote author="Лао-цзи (Дао де цзін)" -Істина, яка може бути виражена словами, не є правдива істина. Ім’я, яке може бути названо, не є правдиве ім’я. +Істина, яка може бути виражена словами, не є правдива істина. Ім'я, яке може бути названо, не є правдиве ім'я. ``` Використання *схожих* імен для *однакових* речей зробить життя цікавішим і продемонструє рівень вашої креативності. -Наприклад, розглянемо префікси функцій. Якщо функція виводить повідомлення на екран -- почніть її ім’я з `display…`, як то `displayMessage`. А для іншої функції, що показуватиме на екрані ще щось (скажімо, ім’я користувача), почніть ім’я з `show…` (наприклад, `showName`). +Наприклад, розглянемо префікси функцій. Якщо функція виводить повідомлення на екран -- почніть її ім'я з `display…`, як то `displayMessage`. А для іншої функції, що показуватиме на екрані ще щось (скажімо, ім'я користувача), почніть ім'я з `show…` (наприклад, `showName`). Натякніть, що є деяка тонка відмінність між цими функціями, хоча насправді її немає. @@ -126,7 +126,7 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0; ```quote author="Лао-цзи (Дао де цзін)" При встановленні порядку
-з’явилися імена.
+з'явилися імена.
Оскільки виникли імена,
потрібно знати межу їх використання. ``` @@ -137,7 +137,7 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0; У функції намагайтесь використовувати лише змінні, що були передані як параметри. -Це суттєво ускладнить розуміння того, що саме міститься в змінній *зараз*, і звідки воно там узялося. Метою цих дій є розвиток інтуїції та пам’яті людини, котра читає ваш код. Людина зі слабкою інтуїцією аналізуватиме такий код рядок за рядком і слідкуватиме за змінами в кожному блоці коду. +Це суттєво ускладнить розуміння того, що саме міститься в змінній *зараз*, і звідки воно там узялося. Метою цих дій є розвиток інтуїції та пам'яті людини, котра читає ваш код. Людина зі слабкою інтуїцією аналізуватиме такий код рядок за рядком і слідкуватиме за змінами в кожному блоці коду. **Просунутим варіантом такого підходу є непомітна (!) заміна значення змінної на щось дуже схоже всередині циклу або функції.** @@ -161,13 +161,13 @@ function ninjaFunction(elem) { Ставте підкреслення `_` та `__` перед іменами змінних. Наприклад, `_name` або `__value`. Краще буде, якщо тільки ви будете розуміти їхнє значення. А ще краще, щоб ніякого значення не було зовсім, додавайте їх задля розваги. Або використовуйте різні значення в різних місцях. -Ви вбиваєте двох зайців одним сюрикеном. По-перше, код стає довшим і менш зрозумілим, і, по-друге, колега-програміст зможе витратити багато часу з’ясовуючи сакральне значення вашого підкреслення. +Ви вбиваєте двох зайців одним сюрикеном. По-перше, код стає довшим і менш зрозумілим, і, по-друге, колега-програміст зможе витратити багато часу з'ясовуючи сакральне значення вашого підкреслення. Проворний ніндзя використовує підкреслення в одній частині коду й уникає їх в іншій. Це робить код ще більш вразливим і підвищує можливість виникнення помилок у майбутньому. ## Покажіть свою любов -Нехай усі бачать, наскільки величні ваші сутності! Читач обов’язково зрадіє таким іменам, як `superElement`, `megaFrame` та `niceItem`. +Нехай усі бачать, наскільки величні ваші сутності! Читач обов'язково зрадіє таким іменам, як `superElement`, `megaFrame` та `niceItem`. Справді, з одного боку, дещо все ж таки написано: `super..`, `mega..`, `nice..`. Але, з іншого боку -- це не пояснює нічого. Той, хто читатиме ваш код, витратить не одну годину свого оплаченого робочого часу на медитацію і пошуки прихованого значення цих слів. @@ -205,11 +205,11 @@ function render() { **Дійсно гарним прийомом є додавати "корисну" дію до них, окрім їхньої основної задачі.** -Вираз приголомшеного подиву на обличчі вашого колеги, коли він побачить, що функція з ім’ям `is..`, `check..` чи `find...` щось змінює, неодмінно розширить межі його свідомості. +Вираз приголомшеного подиву на обличчі вашого колеги, коли він побачить, що функція з ім'ям `is..`, `check..` чи `find...` щось змінює, неодмінно розширить межі його свідомості. **Іншим способом здивувати є повернення нестандартного результату.** -Покажіть своє оригінальне мислення! Нехай виклик функції `checkPermission` поверне не `true/false`, а складний об’єкт з результатом перевірки. +Покажіть своє оригінальне мислення! Нехай виклик функції `checkPermission` поверне не `true/false`, а складний об'єкт з результатом перевірки. Програмісти, що намагатимуться написати `if (checkPermission(..))`, будуть дивуватись, чому воно не працює. Скажіть їм: "Вивчайте документацію!". І дайте їм почитати цю статтю. @@ -221,7 +221,7 @@ function render() { Воно є і праворуч, і ліворуч. ``` -Не треба обмежувати алгоритм функції лише тим, що пов’язано з її ім’ям. Мисліть ширше. +Не треба обмежувати алгоритм функції лише тим, що пов'язано з її ім'ям. Мисліть ширше. Наприклад, функція `validateEmail(email)` може (окрім перевірки адреси електронної пошти на відповідність правилам) показувати повідомлення про помилку та пропонувати ввести нову адресу. diff --git a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md index 215f14e3e..3a0f00844 100644 --- a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md +++ b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md @@ -4,7 +4,7 @@ Іноді простіше написати таким чином, але якщо трапляється помилка, стає не очевидно, що пішло не так. -Якщо помилка трапляється посеред складного потоку виконання, то нам доведеться з’ясувати які були дані на той момент. Тобто, нам доведеться *налагоджувати тест*. +Якщо помилка трапляється посеред складного потоку виконання, то нам доведеться з'ясувати які були дані на той момент. Тобто, нам доведеться *налагоджувати тест*. Було б набагато краще розбити тест на кілька блоків `it` із чітко прописаними вхідними даними та результатами. diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md index efe815dfc..4a45d7e34 100644 --- a/1-js/03-code-quality/05-testing-mocha/article.md +++ b/1-js/03-code-quality/05-testing-mocha/article.md @@ -16,7 +16,7 @@ Наприклад, ми створили функцію `f`. Перевірили деякий код, тестуємо: `f(1)` працює, але `f(2)` не працює. Ми підправляємо код і тепер `f(2)` працює. Здається, що справу зроблено? Але ми забули перевірити чи `f(1)` досі працює. Це може призвести до помилки. -Це дуже типово. Коли ми щось розробляємо, ми пам’ятаємо про багато можливих випадків використання. Але не треба очікувати, що програміст перевірятиме їх усі вручну після кожної зміни. Так стає легко виправити щось одне і зламати інше. +Це дуже типово. Коли ми щось розробляємо, ми пам'ятаємо про багато можливих випадків використання. Але не треба очікувати, що програміст перевірятиме їх усі вручну після кожної зміни. Так стає легко виправити щось одне і зламати інше. **Автоматизоване тестування означає, що тести пишуться окремо від основного коду, доповнюючи його. Вони запускають наші функції різними способами і порівнюють результати з очікуваними.** @@ -96,7 +96,7 @@ describe("pow", function() { ```html src="index.html" ``` -Сторінку можна розділити на п’ять частин: +Сторінку можна розділити на п'ять частин: 1. `` містить сторонні бібліотеки та стилі для тестів. 2. ` -Бачите? Тег `` з’явився з нізвідки. Ми повинні мати це на увазі під час роботи з таблицями, щоб уникати сюрпризів. +Бачите? Тег `` з'явився з нізвідки. Ми повинні мати це на увазі під час роботи з таблицями, щоб уникати сюрпризів. ```` ## Інші типи вузлів @@ -201,7 +201,7 @@ drawHtmlTree(node6, 'div.domtree', 690, 500); Навіть директива `` на самому початку HTML також є вузлом DOM. Вона є DOM дереві прямо перед ``. Мало хто знає про це. Ми не збираємося звертатися до цього вузла, ми навіть не малюємо його на діаграмах, але він там є. -Об’єкт `document`, який представляє весь документ, формально також є вузлом DOM. +Об'єкт `document`, який представляє весь документ, формально також є вузлом DOM. Існує [12 типів вузлів](https://dom.spec.whatwg.org/#node). На практиці ми зазвичай працюємо з 4-ма з них: diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md index b665a1208..8682b4092 100644 --- a/2-ui/1-document/03-dom-navigation/article.md +++ b/2-ui/1-document/03-dom-navigation/article.md @@ -7,9 +7,9 @@ libs: # Навігація по DOM -DOM дозволяє нам робити будь-що з елементами та їх вмістом, але спочатку нам потрібно отримати відповідний DOM об’єкт. +DOM дозволяє нам робити будь-що з елементами та їх вмістом, але спочатку нам потрібно отримати відповідний DOM об'єкт. -Усі операції з DOM починаються з об’єкта `document`. Це головна "точка входу" в DOM. З нього ми можемо отримати доступ до будь-якого вузла. +Усі операції з DOM починаються з об'єкта `document`. Це головна "точка входу" в DOM. З нього ми можемо отримати доступ до будь-якого вузла. Ось так виглядають основні посилання, які дозволяють переміщатися між вузлами DOM: @@ -129,7 +129,7 @@ elem.childNodes[elem.childNodes.length - 1] === elem.lastChild ### DOM колекції -Як бачимо, `childNodes` виглядає як масив. Але насправді це не масив, а скоріше *колекція* -- спеціальний ітеративний об’єкт-псевдомасив. +Як бачимо, `childNodes` виглядає як масив. Але насправді це не масив, а скоріше *колекція* -- спеціальний ітеративний об'єкт-псевдомасив. Є два важливих наслідки з цього: @@ -139,7 +139,7 @@ elem.childNodes[elem.childNodes.length - 1] === elem.lastChild alert(node); // показує всі вузли з колекції } ``` - Це працює, бо колекція є ітерованим об’єктом (є потрібний для цього метод `Symbol.iterator`). + Це працює, бо колекція є ітерованим об'єктом (є потрібний для цього метод `Symbol.iterator`). 2. Методи масиву не працюватимуть, бо колекція це не масив: ```js run @@ -163,7 +163,7 @@ elem.childNodes[elem.childNodes.length - 1] === elem.lastChild ```warn header="DOM колецкції живі" Майже всі колекції DOM, за незначними винятками, є *живими*. Іншими словами, вони завжди відображають поточний стан DOM. -Якщо ми зберегли посилання на `elem.childNodes` і після цього додамо/видалимо вузли в DOM, вони автоматично з’являться в колекції. +Якщо ми зберегли посилання на `elem.childNodes` і після цього додамо/видалимо вузли в DOM, вони автоматично з'являться в колекції. ``` ````warn header="Не використовуйте `for..in` для перебору колекцій" diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md index ae6a8c6f3..9b7aa13bc 100644 --- a/2-ui/1-document/04-searching-elements-dom/article.md +++ b/2-ui/1-document/04-searching-elements-dom/article.md @@ -37,12 +37,12 @@ // elem -- це посилання на елемент DOM з id="elem" elem.style.background = 'red'; - // id="elem-content" містить дефіс всередині, тому не може бути ім’ям змінної + // id="elem-content" містить дефіс всередині, тому не може бути ім'ям змінної // ...але ми можемо отримати доступ до нього за допомогою квадратних дужок: window['elem-content'] ``` -...Але це лише якщо ми не оголосили змінну JavaScript з таким же ім’ям, інакше вона матиме пріоритет: +...Але це лише якщо ми не оголосили змінну JavaScript з таким же ім'ям, інакше вона матиме пріоритет: ```html run untrusted height=0
@@ -71,7 +71,7 @@ ``` ```warn header="Лише `document.getElementById`, а не `anyElem.getElementById`" -Метод `getElementById` може бути викликаний лише на об’єкті `document`. Він шукає вказаний `id` у всьому документі. +Метод `getElementById` може бути викликаний лише на об'єкті `document`. Він шукає вказаний `id` у всьому документі. ``` ## querySelectorAll [#querySelectorAll] @@ -251,7 +251,7 @@ document.getElementsByTagName('input')[0].value = 5; diff --git a/2-ui/1-document/06-dom-attributes-and-properties/article.md b/2-ui/1-document/06-dom-attributes-and-properties/article.md index 620e623b8..39e9dfbcd 100644 --- a/2-ui/1-document/06-dom-attributes-and-properties/article.md +++ b/2-ui/1-document/06-dom-attributes-and-properties/article.md @@ -1,8 +1,8 @@ # Атрибути та властивості -Коли браузер завантажує сторінку, він "читає" (іншими словами: "парсить") HTML і генерує DOM об’єкти з нього. Для вузлів-елементів більшість стандартних атрибутів HTML автоматично стають властивостями об'єктів DOM. +Коли браузер завантажує сторінку, він "читає" (іншими словами: "парсить") HTML і генерує DOM об'єкти з нього. Для вузлів-елементів більшість стандартних атрибутів HTML автоматично стають властивостями об'єктів DOM. -Наприклад, якщо тег це ``, тоді об’єкт DOM матиме `body.id="page"`. +Наприклад, якщо тег це ``, тоді об'єкт DOM матиме `body.id="page"`. Але представлення атрибутів через властивості не відбувається один до одного! У цій главі ми звернемо увагу на відмінності цих двох концепцій, щоб навчитись, як з ними працювати, коли вони співпадають і коли відрізняються. @@ -10,7 +10,7 @@ Ми вже бачили вбудовані властивості DOM. Їх багато. Але технічно ніхто нас не обмежує, і якщо їх недостатньо, ми можемо додати власні. -DOM вузли є звичайними об’єктами JavaScript. Ми можемо змінювати їх. +DOM вузли є звичайними об'єктами JavaScript. Ми можемо змінювати їх. Наприклад, створімо нову властивість у `document.body`: @@ -44,7 +44,7 @@ document.documentElement.sayHi(); // Привіт, Я HTML document.body.sayHi(); // Привіт, Я BODY ``` -Отже, властивості та методи DOM поводяться так само, як і звичайні об’єкти JavaScript: +Отже, властивості та методи DOM поводяться так само, як і звичайні об'єкти JavaScript: - Вони можуть мати будь-яке значення. - Вони чутливі до регістру (наприклад `elem.nodeType`, не `elem.NoDeTyPe`). @@ -201,7 +201,7 @@ document.body.sayHi(); // Привіт, Я BODY ``` -Є й інші приклади. Атрибут `style` -- це рядок, але властивість `style` є об’єктом: +Є й інші приклади. Атрибут `style` -- це рядок, але властивість `style` є об'єктом: ```html run
Привіт
@@ -210,7 +210,7 @@ document.body.sayHi(); // Привіт, Я BODY // рядок alert(div.getAttribute('style')); // color:red;font-size:120% - // об’єкт + // об'єкт alert(div.style); // [object CSSStyleDeclaration] alert(div.style.color); // red @@ -307,7 +307,7 @@ document.body.sayHi(); // Привіт, Я BODY div.setAttribute('order-state', 'canceled'); ``` -Але може виникнути потенційна проблема з користувацькими атрибутами. Що робити, якщо ми використовуємо нестандартний атрибут для наших цілей, а потім стандарт вводить його та надає йому якусь функціональність? Мова HTML жива, вона зростає, а також з’являється більше атрибутів, які відповідають потребам розробників. У такому випадку можуть виникнути неочікувані наслідки. +Але може виникнути потенційна проблема з користувацькими атрибутами. Що робити, якщо ми використовуємо нестандартний атрибут для наших цілей, а потім стандарт вводить його та надає йому якусь функціональність? Мова HTML жива, вона зростає, а також з'являється більше атрибутів, які відповідають потребам розробників. У такому випадку можуть виникнути неочікувані наслідки. Щоб уникнути конфліктів, існують [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) атрибути. @@ -363,7 +363,7 @@ div.setAttribute('order-state', 'canceled'); ## Підсумки - Атрибути -- це те, що написано в HTML. -- Властивості -- це те, що є в об’єктах DOM. +- Властивості -- це те, що є в об'єктах DOM. Невелике порівняння: diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md index 431c9f736..f52f4fdcc 100644 --- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md +++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md @@ -54,4 +54,4 @@ function clockStop() { Будь ласка, зверніть увагу, що виклик `update()` не тільки заплановано в `clockStart()`, а ще й негайно виконується в рядку `(*)`. Інакше відвідувач повинен був би чекати до першого виконання `setInterval`. І до того часу годинник був би порожнім. -Також важливо встановити новий інтервал у `clockStart()` лише тоді, коли годинник не працює. Інакше натискання кнопки «Пуск» кілька разів встановить кілька одночасних інтервалів. Ще гірше -- ми запам’ятаємо лише `timerID` останнього інтервалу, втративши посилання на всі інші. В такому разі ми б ніколи більше не змогли зупинити годинник! Зауважте, в рядку `(**)` нам потрібно очистити `timerID`, коли годинник зупинено, щоб його можна було знову увімкнути, запустивши `clockStart()`. +Також важливо встановити новий інтервал у `clockStart()` лише тоді, коли годинник не працює. Інакше натискання кнопки «Пуск» кілька разів встановить кілька одночасних інтервалів. Ще гірше -- ми запам'ятаємо лише `timerID` останнього інтервалу, втративши посилання на всі інші. В такому разі ми б ніколи більше не змогли зупинити годинник! Зауважте, в рядку `(**)` нам потрібно очистити `timerID`, коли годинник зупинено, щоб його можна було знову увімкнути, запустивши `clockStart()`. diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/solution.md b/2-ui/1-document/07-modifying-document/12-sort-table/solution.md index 11d411f00..ee963f1a0 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/solution.md +++ b/2-ui/1-document/07-modifying-document/12-sort-table/solution.md @@ -10,7 +10,7 @@ table.tBodies[0].append(...sortedRows); // (3) Покроковий алгоритм: 1. Отримати всі `` з ``. -2. Потім відсортувати їх порівнюючи за вмістом першого `` (поле «Ім’я»). +2. Потім відсортувати їх порівнюючи за вмістом першого `` (поле «Ім'я»). 3. Вставити вузли в правильному порядку `.append(...sortedRows)`. Нам не потрібно видаляти існуючі рядки з таблиці, лише повторно вставити і вони автоматично залишать своє попереднє місце розташування. diff --git a/2-ui/1-document/07-modifying-document/12-sort-table/task.md b/2-ui/1-document/07-modifying-document/12-sort-table/task.md index 1ddfa7c50..0dc60fd3d 100644 --- a/2-ui/1-document/07-modifying-document/12-sort-table/task.md +++ b/2-ui/1-document/07-modifying-document/12-sort-table/task.md @@ -10,7 +10,7 @@ importance: 5 - + diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md b/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md index 317a414ed..0091ecb7c 100644 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/solution.md @@ -1,4 +1,4 @@ -Найпростіший спосіб обійти об’єкт -- скористатися рекурсією. +Найпростіший спосіб обійти об'єкт -- скористатися рекурсією. 1. [Рішення з innerHTML](sandbox:innerhtml). 2. [Рішення з DOM](sandbox:build-tree-dom). diff --git a/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md b/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md index 79aa5a984..aa961bb76 100644 --- a/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md +++ b/2-ui/1-document/07-modifying-document/7-create-object-tree/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Створіть дерево з об’єкту +# Створіть дерево з об'єкту -Напишіть функцію `createTree` яка створює вкладений `ul/li` список з вкладеного об’єкта. +Напишіть функцію `createTree` яка створює вкладений `ul/li` список з вкладеного об'єкта. Наприклад: diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md index 42484b8c6..de2ef8860 100644 --- a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md +++ b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md @@ -3,7 +3,7 @@ Алгоритм: 1. Створіть заголовок таблиці з ``. 4. Збільшуйте день `d`: `d.setDate(d.getDate()+1)`. Якщо `d.getMonth()` ще не досяг наступного місяця, тоді додайте нову клітинку ` *!* - + */!* diff --git a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md index 31bbbad3f..ca9e41e78 100644 --- a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md +++ b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md @@ -6,7 +6,7 @@ importance: 5 Створіть JS-код для поведінки спливаючої підказки. -При наведенні миші на елемент з `data-tooltip`, підказка має з’явитися над ним і ховатися при переході на інший елемент. +При наведенні миші на елемент з `data-tooltip`, підказка має з'явитися над ним і ховатися при переході на інший елемент. Приклад HTML з підказками: ```html diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md index 66bcb6390..fb236a86a 100644 --- a/2-ui/2-events/03-event-delegation/article.md +++ b/2-ui/2-events/03-event-delegation/article.md @@ -83,7 +83,7 @@ function highlight(td) { ![](bagua-bubble.svg) -В обробнику `table.onclick` ми повинні взяти `event.target` і з’ясувати, чи був клік всередині `
Ім’яПрізвищеВікІм'яПрізвищеВік
` та днями тижня. -2. Створіть об’єкт дати `d = new Date(year, month-1)`. Це перший день місяця `month` (беручи до уваги, що місяці в JavaScript починаються з `0`, а не з `1`). +2. Створіть об'єкт дати `d = new Date(year, month-1)`. Це перший день місяця `month` (беручи до уваги, що місяці в JavaScript починаються з `0`, а не з `1`). 3. Декілька перших клітинок до `d.getDay()` можуть бути пустими. Заповнимо їх `` в календар. Якщо це НД, тоді додайте новий рядок "</tr><tr>". 5. Якщо міcяць завершився, але рядок таблиці ще не заповнений, додайте пусті ``, щоб надати таблиці правильної форми. diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md index 4f1bbdbdc..693dbdb01 100644 --- a/2-ui/1-document/07-modifying-document/article.md +++ b/2-ui/1-document/07-modifying-document/article.md @@ -69,7 +69,7 @@ div.innerHTML = "Всім привіт! Ви прочитали ## Методи вставки -Щоб `div` з’явився нам потрібно вставити його десь в `document`. Наприклад, в елемент `` який можна отримати звернувшись до `document.body`. +Щоб `div` з'явився нам потрібно вставити його десь в `document`. Наприклад, в елемент `` який можна отримати звернувшись до `document.body`. Для цього існує спеціальний метод `append`: `document.body.append(div)`. @@ -163,7 +163,7 @@ after ``` -Пам’ятайте, що текст вставляється «як текст», а не «як HTML», з відповідними замінами таких символів як `<`, `>`. +Пам'ятайте, що текст вставляється «як текст», а не «як HTML», з відповідними замінами таких символів як `<`, `>`. Тому фінальний HTML буде таким: diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 57f354a90..67ac967eb 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -27,7 +27,7 @@ elem.style.top = top; // наприклад '456px' Зміна класу є однією з найчастіше використовуваних дій у скриптах. -В давні часи JavaScript мав певні обмеження: зарезервоване слово, таке як `"class"`, не могло бути властивістю об’єкта. Цього обмеження наразі більше немає, проте на той час було неможливо мати властивість `"class"`, як от `elem.class`. +В давні часи JavaScript мав певні обмеження: зарезервоване слово, таке як `"class"`, не могло бути властивістю об'єкта. Цього обмеження наразі більше немає, проте на той час було неможливо мати властивість `"class"`, як от `elem.class`. Тому для класів було додано схожу на вигляд властивість `"className"`: `elem.className` відповідає атрибуту `"class"`. @@ -45,7 +45,7 @@ elem.style.top = top; // наприклад '456px' Для цього існує інша властивість, а саме `elem.classList`. -Властивість `elem.classList` -- це спеціальний об’єкт, який містить методи для додавання, видалення або перемикання окремого класу. +Властивість `elem.classList` -- це спеціальний об'єкт, який містить методи для додавання, видалення або перемикання окремого класу. Наприклад: @@ -70,7 +70,7 @@ elem.style.top = top; // наприклад '456px' - `elem.classList.toggle("class")` -- додає клас, якщо він не існує, інакше видаляє його. - `elem.classList.contains("class")` -- перевіряє, чи існує переданий клас, відповідно повертає `true/false`. -Крім того, `classList` -- це ітерований об’єкт, тому можна легко вивести перелік всіх класів циклом `for..of`, як показано далі: +Крім того, `classList` -- це ітерований об'єкт, тому можна легко вивести перелік всіх класів циклом `for..of`, як показано далі: ```html run @@ -84,7 +84,7 @@ elem.style.top = top; // наприклад '456px' ## Стилі елемента -Властивість `elem.style` -- це об’єкт, вміст якого відповідає тому, що записано в атрибуті `"style"`. Встановлення `elem.style.width="100px"` працює точнісінько так само, як рядок `width:100px` записаний в атрибут `style`. +Властивість `elem.style` -- це об'єкт, вміст якого відповідає тому, що записано в атрибуті `"style"`. Встановлення `elem.style.width="100px"` працює точнісінько так само, як рядок `width:100px` записаний в атрибут `style`. Для властивостей, які називаються кількома словами, використовується верблюдячий регістр (camelCase): @@ -137,7 +137,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в ``` ````smart header="Повний перезапис за допомогою `style.cssText`" -Зазвичай, `style.*` використовується для встановлення окремих властивостей стилю. Немає можливості задати весь стиль, як от `div.style="color: red; width: 100px"`, оскільки `div.style` -- це об’єкт, і він доступний лише для читання. +Зазвичай, `style.*` використовується для встановлення окремих властивостей стилю. Немає можливості задати весь стиль, як от `div.style="color: red; width: 100px"`, оскільки `div.style` -- це об'єкт, і він доступний лише для читання. Існує спеціальна властивість `style.cssText`, яка дає змогу встановлювати повний стиль елемента як рядок: @@ -161,7 +161,7 @@ setTimeout(() => document.body.style.removeProperty('background'), 1000); // в Того самого можна досягнути шляхом встановлення значення атрибута: `div.setAttribute('style', 'color: red...')`. ```` -## Пам’ятайте про одиниці вимірювання +## Пам'ятайте про одиниці вимірювання Не забувайте додавати одиниці вимірювання CSS до значень. @@ -232,7 +232,7 @@ element pseudo : Вказується, якщо потрібен стиль псевдоелемента, наприклад: `::before`. Порожній рядок, або опущений аргумент означатимуть, що буде опрацьовано сам елемент. -В результаті виклику методу буде повернено об’єкт зі стилями, подібно до `elem.style`, але зі врахуванням всіх класів CSS. +В результаті виклику методу буде повернено об'єкт зі стилями, подібно до `elem.style`, але зі врахуванням всіх класів CSS. Наприклад: @@ -284,14 +284,14 @@ JavaScript не бачить стилі, застосовані через се Існує дві властивості DOM для керування класами: - `className` -- рядкове значення, гарно підходить для керування всім набором класів елемента в цілому. -- `classList` -- об’єкт з методами `add/remove/toggle/contains`, підходить для роботи з окремими класами. +- `classList` -- об'єкт з методами `add/remove/toggle/contains`, підходить для роботи з окремими класами. Для зміни стилів: -- Властивість `style` -- об’єкт зі стилями, записаними верблюдячим регістром (camelCase). Читання і запис у неї має такий самий зміст, як і модифікація окремих властивостей в атрибуті `"style"`. Щоб побачити, як застосовується `important` та інші рідкісні речі -- на [MDN](mdn:api/CSSStyleDeclaration) описано перелік методів. +- Властивість `style` -- об'єкт зі стилями, записаними верблюдячим регістром (camelCase). Читання і запис у неї має такий самий зміст, як і модифікація окремих властивостей в атрибуті `"style"`. Щоб побачити, як застосовується `important` та інші рідкісні речі -- на [MDN](mdn:api/CSSStyleDeclaration) описано перелік методів. - Властивість `style.cssText` показує атрибут `"style"` в цілому, весь рядок стилів. Для зчитування кінцевих стилів (з врахуванням всіх класів, після застосування всього CSS і обчислення остаточних значень): -- Метод `getComputedStyle(elem, [pseudo])` повертає об’єкт, подібний до властивості `style`, з кінцевими значеннями. Виключно для читання. +- Метод `getComputedStyle(elem, [pseudo])` повертає об'єкт, подібний до властивості `style`, з кінцевими значеннями. Виключно для читання. diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index 16c7269ea..475bdf19b 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -256,7 +256,7 @@ alert( getComputedStyle(elem).width ); // показує CSS-ширину elem Елемент із текстом має CSS `width:300px`. -На комп’ютері в ОС Windows, Firefox, Chrome, Edge резервується місце для смуги прокрутки. Але Firefox показує `300px`, а Chrome і Edge -- менше. Це тому, що Firefox повертає ширину CSS, а інші браузери повертають "реальну" ширину. +На комп'ютері в ОС Windows, Firefox, Chrome, Edge резервується місце для смуги прокрутки. Але Firefox показує `300px`, а Chrome і Edge -- менше. Це тому, що Firefox повертає ширину CSS, а інші браузери повертають "реальну" ширину. ``` Зверніть увагу, що описана різниця стосується лише читання `getComputedStyle(...).width` з JavaScript, візуально все правильно. diff --git a/2-ui/1-document/10-size-and-scroll-window/article.md b/2-ui/1-document/10-size-and-scroll-window/article.md index 86f355c02..0e627e7ba 100644 --- a/2-ui/1-document/10-size-and-scroll-window/article.md +++ b/2-ui/1-document/10-size-and-scroll-window/article.md @@ -62,7 +62,7 @@ alert('Повна висота документа з прокрученою ча Стан прокрутки документа міститься в `document.documentElement.scrollLeft/scrollTop`, та працює в більшості браузерів, за винятком старіших браузерів створених на WebKit, таких як Safari (помилка [5991](https://bugs.webkit.org/show_bug.cgi?id=5991)), де ми повинні використовувати `document.body` замість `document.documentElement`. -На щастя, нам не потрібно пам’ятати про ці особливості, оскільки прокрутка доступна у спеціальних властивостях `window.pageXOffset/pageYOffset`: +На щастя, нам не потрібно пам'ятати про ці особливості, оскільки прокрутка доступна у спеціальних властивостях `window.pageXOffset/pageYOffset`: ```js run alert('Поточна прокрутка зверху: ' + window.pageYOffset); @@ -112,8 +112,8 @@ alert('Поточна прокрутка зліва: ' + window.pageXOffset); Виклик `elem.scrollIntoView(top)` прокручує сторінку таким чином, щоб зробити `elem` видимим. Він має один аргумент: -- Якщо `top=true` (типове значення), то сторінка буде прокручена так, щоб `elem` з’явився у верхній частині вікна. Верхній край елемента буде вирівняний з верхньою частиною вікна. -- Якщо `top=false`, то сторінка прокручується так, щоб `elem` з’явився внизу. Нижній край елемента буде вирівняний з нижньою частиною вікна. +- Якщо `top=true` (типове значення), то сторінка буде прокручена так, щоб `elem` з'явився у верхній частині вікна. Верхній край елемента буде вирівняний з верхньою частиною вікна. +- Якщо `top=false`, то сторінка прокручується так, щоб `elem` з'явився внизу. Нижній край елемента буде вирівняний з нижньою частиною вікна. ```online Кнопка нижче прокручує сторінку, щоб розмістити себе у верхній частині вікна: diff --git a/2-ui/1-document/11-coordinates/1-find-point-coordinates/task.md b/2-ui/1-document/11-coordinates/1-find-point-coordinates/task.md index 049eac3d1..4b3ef7fc5 100644 --- a/2-ui/1-document/11-coordinates/1-find-point-coordinates/task.md +++ b/2-ui/1-document/11-coordinates/1-find-point-coordinates/task.md @@ -21,4 +21,4 @@ Обчислені координати повинні збігатися з тими, які повертаються клацанням миші. -P.S. Код також повинен працювати, якщо елемент має інший розмір або рамку, тобто не прив’язаний до жодних фіксованих значень. +P.S. Код також повинен працювати, якщо елемент має інший розмір або рамку, тобто не прив'язаний до жодних фіксованих значень. diff --git a/2-ui/1-document/11-coordinates/3-position-at-absolute/task.md b/2-ui/1-document/11-coordinates/3-position-at-absolute/task.md index c48348079..84ff31301 100644 --- a/2-ui/1-document/11-coordinates/3-position-at-absolute/task.md +++ b/2-ui/1-document/11-coordinates/3-position-at-absolute/task.md @@ -8,4 +8,4 @@ Це запобіжить «втечу» нотатки від елемента під час прокручування сторінки. -Візьміть розв’язання попереднього завдання за відправну точку. Щоб перевірити прокрутку, додайте стиль ``. +Візьміть розв'язання попереднього завдання за відправну точку. Щоб перевірити прокрутку, додайте стиль ``. diff --git a/2-ui/1-document/11-coordinates/4-position-inside-absolute/task.md b/2-ui/1-document/11-coordinates/4-position-inside-absolute/task.md index ce5a61c2f..49e8320a8 100644 --- a/2-ui/1-document/11-coordinates/4-position-inside-absolute/task.md +++ b/2-ui/1-document/11-coordinates/4-position-inside-absolute/task.md @@ -25,4 +25,4 @@ positionAt(blockquote, "top-in", note); [iframe src="solution" height="310" border="1" link] -Для початку візьміть розв’язання задачі . +Для початку візьміть розв'язання задачі . diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md index fca00d4dd..8262b6255 100644 --- a/2-ui/1-document/11-coordinates/article.md +++ b/2-ui/1-document/11-coordinates/article.md @@ -21,14 +21,14 @@ ## Координати елемента відносно вікна: getBoundingClientRect -Метод `elem.getBoundingClientRect()` повертає координати у контексті вікна для мінімального за розмірами прямокутника, який вміщує `elem` у вигляді об’єкта вбудованого класу [DOMRect](https://www.w3.org/TR/geometry-1/#domrect). +Метод `elem.getBoundingClientRect()` повертає координати у контексті вікна для мінімального за розмірами прямокутника, який вміщує `elem` у вигляді об'єкта вбудованого класу [DOMRect](https://www.w3.org/TR/geometry-1/#domrect). Основні властивості `DOMRect`: - `x/y` -- координати X/Y початку прямокутника відносно вікна, -- `width/height` -- ширина/висота прямокутника (можуть бути від’ємними). +- `width/height` -- ширина/висота прямокутника (можуть бути від'ємними). -Крім того, в об’єкті містяться такі похідні властивості: +Крім того, в об'єкті містяться такі похідні властивості: - `top/bottom` -- Y-координата для верхнього/нижнього краю прямокутника, - `left/right` -- X-координата для лівого/правого краю прямокутника. @@ -70,16 +70,16 @@ right:${r.right} Зверніть увагу: - Координати можуть бути десятковими дробами, наприклад `10.5`. Це нормально, тому, що внутрішньо браузер використовує дроби у своїх обчисленнях. Нам не потрібно їх округлювати, коли встановлюємо значення `style.left/top`. -– Координати можуть бути від’ємними. Наприклад, якщо сторінка прокручена таким чином, що `elem` знаходиться над видимою частиною вікна, то `elem.getBoundingClientRect().top` буде від’ємними. +– Координати можуть бути від'ємними. Наприклад, якщо сторінка прокручена таким чином, що `elem` знаходиться над видимою частиною вікна, то `elem.getBoundingClientRect().top` буде від'ємними. ```smart header="Навіщо потрібні похідні властивості? Чому існує `top/left`, якщо є `x/y`?" Математично прямокутник однозначно визначається його початковою точкою `(x,y)` і вектором напрямку `(width,height)`. Тому додаткові похідні властивості призначені для зручності. -Технічно можливо, щоб `width/height` були від’ємними, це дозволяє використовувати «спрямований» прямокутник, наприклад для представлення виділення мишею з правильно позначеними початком і кінцем. +Технічно можливо, щоб `width/height` були від'ємними, це дозволяє використовувати «спрямований» прямокутник, наприклад для представлення виділення мишею з правильно позначеними початком і кінцем. -Від’ємні значення `width/height` означають, що прямокутник починається з нижнього правого кута, а потім "зростає" ліворуч вгору. +Від'ємні значення `width/height` означають, що прямокутник починається з нижнього правого кута, а потім "зростає" ліворуч вгору. -Ось прямокутник із від’ємними значеннями `width` і `height` (наприклад, `width=-200`, `height=-100`): +Ось прямокутник із від'ємними значеннями `width` і `height` (наприклад, `width=-200`, `height=-100`): ![](coordinates-negative.svg) @@ -129,7 +129,7 @@ alert(elem.tagName); ````warn header="Для координат, які знаходяться поза вікном `elementFromPoint` повертає `null`" Метод `document.elementFromPoint(x,y)` працює, лише якщо координати `(x,y)` знаходяться у видимій області вікна. -Якщо будь-яка з координат від’ємна, або більша ніж ширина/висота вікна, то повертається `null`. +Якщо будь-яка з координат від'ємна, або більша ніж ширина/висота вікна, то повертається `null`. Ось типова помилка, яка може виникнути, якщо не додати перевірку: @@ -182,7 +182,7 @@ setTimeout(() => message.remove(), 5000); ```online Натисніть кнопку, щоб запустити приклад: - + ``` Код можна змінити, щоб показати повідомлення ліворуч, праворуч, знизу, застосувати CSS анімацію, і так далі. Це легко, оскільки у нас є всі координати та розміри елемента. @@ -203,7 +203,7 @@ setTimeout(() => message.remove(), 5000); Не існує стандартного методу для отримання координат елемента відносно до документа. Але написати його легко. -Дві системи координат з’єднуються за формулою: +Дві системи координат з'єднуються за формулою: - `pageY` = `clientY` + висота прокрученої вертикальної частини документа. - `pageX` = `clientX` + ширина прокрученої горизонтальної частини документа. diff --git a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md index 92e54355c..f34312ce8 100644 --- a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md +++ b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/solution.md @@ -1,11 +1,11 @@ -Спочатку ми маємо вибрати метод позиціювання м’яча. +Спочатку ми маємо вибрати метод позиціювання м'яча. -Ми не можемо використати `position:fixed` для цього, оскільки прокручування сторінки переміщатиме м’яч поля. +Ми не можемо використати `position:fixed` для цього, оскільки прокручування сторінки переміщатиме м'яч поля. Правильніше використовувати `position:absolute` і, щоб зробити позиціювання справді надійним, зробимо саме поле `field` позиціонованим. -Тоді м’яч буде позиціонований щодо поля: +Тоді м'яч буде позиціонований щодо поля: ```css #field { @@ -18,7 +18,7 @@ position: absolute; left: 0; /* по відношенню до найближчого розташованого предка (field) */ top: 0; - transition: 1s all; /* CSS-анімація для значень left/top робить пересування м’яча плавним */ + transition: 1s all; /* CSS-анімація для значень left/top робить пересування м'яча плавним */ } ``` @@ -30,15 +30,15 @@ Ми маємо `event.clientX/clientY` -- координати натискання мишки щодо вікна браузера. -Щоб отримати значення `left` для м’яча після натискання мишки щодо поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі: +Щоб отримати значення `left` для м'яча після натискання мишки щодо поля, ми повинні від координати натискання мишки відняти координату лівого краю поля та ширину межі: ```js let left = event.clientX - fieldCoords.left - field.clientLeft; ``` -Значення `ball.style.left` означає «лівий край елемента» (м’яча). І якщо ми призначимо такий `left` для м’яча, то його ліва межа, а не центр, буде під курсором миші. +Значення `ball.style.left` означає «лівий край елемента» (м'яча). І якщо ми призначимо такий `left` для м'яча, то його ліва межа, а не центр, буде під курсором миші. -Нам потрібно зрушити м'яч на половину його висоти вгору та половину його ширини вліво, щоб центр м’яча точно збігався з точкою натискання мишки. +Нам потрібно зрушити м'яч на половину його висоти вгору та половину його ширини вліво, щоб центр м'яча точно збігався з точкою натискання мишки. У результаті значення для `left` буде таким: @@ -48,4 +48,4 @@ let left = event.clientX - fieldCoords.left - field.clientLeft - ball.offsetWidt Вертикальна координата обчислюватиметься за тією ж логікою. -Слід пам’ятати, що ширина та висота м’яча має бути відома в той момент, коли ми отримуємо значення `ball.offsetWidth`. Це значення може бути задано в HTML або CSS. +Слід пам'ятати, що ширина та висота м'яча має бути відома в той момент, коли ми отримуємо значення `ball.offsetWidth`. Це значення може бути задано в HTML або CSS. diff --git a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/task.md b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/task.md index ab0fca0aa..d8c92a8c0 100644 --- a/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/task.md +++ b/2-ui/2-events/01-introduction-browser-events/04-move-ball-field/task.md @@ -2,20 +2,20 @@ importance: 5 --- -# Пересуньте м’яч по полю +# Пересуньте м'яч по полю -Нехай м’яч переміщається при натисканні на поле, туди, де був клік, ось так: +Нехай м'яч переміщається при натисканні на поле, туди, де був клік, ось так: [iframe src="solution" height="260" link] Вимоги: -- Центр м’яча повинен збігатися з курсором миші (якщо це можливо без перетину країв поля); -- CSS-анімація бажана, але не є обов’язковою; -- М’яч у жодному разі не повинен перетинати межі поля; +- Центр м'яча повинен збігатися з курсором миші (якщо це можливо без перетину країв поля); +- CSS-анімація бажана, але не є обов'язковою; +- М'яч у жодному разі не повинен перетинати межі поля; - При прокручуванні сторінки нічого не повинно ламатися; Нотатки: -- Код повинен уміти працювати з різними розмірами м’яча та поля, не прив’язуватися до будь-яких фіксованих значень. +- Код повинен уміти працювати з різними розмірами м'яча та поля, не прив'язуватися до будь-яких фіксованих значень. - Використовуйте властивості `event.clientX/event.clientY`, щоб вирахувати координати миші при кліці. diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index 5b5d7dfa1..600422567 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -64,9 +64,9 @@ ``` -Як ми пам’ятаємо, атрибут HTML-тега не чутливий до регістру, тому `ONCLICK` буде працювати так само як `onClick` і `onCLICK`… Але, як правило, атрибути пишуть у нижньому регістрі `onclick`. +Як ми пам'ятаємо, атрибут HTML-тега не чутливий до регістру, тому `ONCLICK` буде працювати так само як `onClick` і `onCLICK`… Але, як правило, атрибути пишуть у нижньому регістрі `onclick`. -### Використання властивостей DOM-об’єкта +### Використання властивостей DOM-об'єкта Можемо призначати обробник, використовуючи властивість DOM-елемента `on`. @@ -109,7 +109,7 @@ У першому прикладі використовувався атрибут HTML для ініціалізації `button.onclick`, тоді як у другому прикладі -- сценарій, ось і вся різниця. -**Оскільки в елемента DOM може бути тільки одна властивість з ім’ям `onclick`, то призначити більше одного обробника таким чином не можна.** +**Оскільки в елемента DOM може бути тільки одна властивість з ім'ям `onclick`, то призначити більше одного обробника таким чином не можна.** У прикладі нижче призначення обробника додатково через JavaScript перезапише обробник з атрибуту: @@ -222,7 +222,7 @@ element.addEventListener(event, handler, [options]); : Посилання на функцію-обробник. `options` -: Додатковий об’єкт із властивостями: +: Додатковий об'єкт із властивостями: - `once`: якщо `true`, тоді обробник буде автоматично вилучений після виконання. - `capture`: фаза, на якій повинен спрацювати обробник, докладніше про це буде розказано у розділі . Так історично склалося, що `options` може бути `false/true`, це те саме, що `{capture: false/true}`. - `passive`: якщо `true`, тоді обробник ніколи не викличе `preventDefault()`, докладніше про це буде розказано у розділі . @@ -306,7 +306,7 @@ document.addEventListener("DOMContentLoaded", function() { Таким чином `addEventListener` більш універсальний. Хоча зауважимо, що таких подій меншість, це скоріше виняток, ніж правило. ```` -## Об’єкт події +## Об'єкт події Щоб правильно обробити подію, можуть знадобитися деталі того, що сталося. Не просто "клік" або "натискання клавіші", але й координати вказівника миші, яка саме клавіша натиснута і так далі. @@ -326,21 +326,21 @@ document.addEventListener("DOMContentLoaded", function() { ``` -Деякі властивості об’єкту `event`: +Деякі властивості об'єкту `event`: `event.type` : Тип події, у цьому випадку `"click"`. `event.currentTarget` -: Елемент, у якому спрацював обробник. Це значення зазвичай таке саме, як і в `this`, але якщо обробник є функцією-стрілкою чи за допомогою `bind` прив’язаний інший об’єкт `this`, то ми можемо отримати елемент з `event.currentTarget`. +: Елемент, у якому спрацював обробник. Це значення зазвичай таке саме, як і в `this`, але якщо обробник є функцією-стрілкою чи за допомогою `bind` прив'язаний інший об'єкт `this`, то ми можемо отримати елемент з `event.currentTarget`. `event.clientX / event.clientY` : Координати курсору в момент кліку у площині вікна для подій миші. Існує багато властивостей подій. Більшість з них залежать від типу події: події клавіатури мають один набір подій, а події вказівника -- інший. Ми розглянемо детальніше деякі з них пізніше. -````smart header="Об’єкт події доступний і в HTML" -При призначенні обробника в HTML теж можна використовувати об’єкт `event`, ось так: +````smart header="Об'єкт події доступний і в HTML" +При призначенні обробника в HTML теж можна використовувати об'єкт `event`, ось так: ```html autorun height=60 @@ -350,9 +350,9 @@ document.addEventListener("DOMContentLoaded", function() { ```` -## Об’єкт-обробник: handleEvent +## Об'єкт-обробник: handleEvent -Ми можемо призначити обробником не лише функцію, а й об’єкт за допомогою `addEventListener`. У такому разі, коли відбувається подія, викликається метод об’єкта `handleEvent`. +Ми можемо призначити обробником не лише функцію, а й об'єкт за допомогою `addEventListener`. У такому разі, коли відбувається подія, викликається метод об'єкта `handleEvent`. Наприклад: @@ -371,7 +371,7 @@ document.addEventListener("DOMContentLoaded", function() { ``` -Як бачимо, якщо `addEventListener` отримує об’єкт як обробник, він викликає `obj.handleEvent(event)`, коли відбувається подія. +Як бачимо, якщо `addEventListener` отримує об'єкт як обробник, він викликає `obj.handleEvent(event)`, коли відбувається подія. Ми також можемо використати клас для цього, ось так: @@ -402,9 +402,9 @@ document.addEventListener("DOMContentLoaded", function() { ``` -Тут той самий об’єкт обробляє обидві події. Зверніть увагу, ми повинні явно призначити обидва обробники через `addEventListener`. Тоді об’єкт `menu` отримуватиме події `mousedown` та `mouseup`, а не інші (не призначені) типи подій. +Тут той самий об'єкт обробляє обидві події. Зверніть увагу, ми повинні явно призначити обидва обробники через `addEventListener`. Тоді об'єкт `menu` отримуватиме події `mousedown` та `mouseup`, а не інші (не призначені) типи подій. -Метод `handleEvent` не обов’язково має виконувати всю роботу сам. Він може викликати інші методи, які створені під обробку конкретних типів подій, ось так: +Метод `handleEvent` не обов'язково має виконувати всю роботу сам. Він може викликати інші методи, які створені під обробку конкретних типів подій, ось так: ```html run @@ -446,8 +446,8 @@ HTML-атрибути використовуються рідко тому, що DOM-властивості можна використовувати, але ми не можемо призначити більше одного обробника на один тип події. У багатьох випадках із цим обмеженням можна миритися. -Останній спосіб найбільш гнучкий, проте потрібно писати більше коду. Є кілька типів подій, які працюють лише через нього, наприклад `transitionend` та `DOMContentLoaded`. Також `addEventListener` підтримує об’єкти-обробники подій. В цьому випадку викликається метод об’єкту `handleEvent`. +Останній спосіб найбільш гнучкий, проте потрібно писати більше коду. Є кілька типів подій, які працюють лише через нього, наприклад `transitionend` та `DOMContentLoaded`. Також `addEventListener` підтримує об'єкти-обробники подій. В цьому випадку викликається метод об'єкту `handleEvent`. -Не важливо, як ви призначаєте обробник, він отримує об’єкт події першим аргументом. Цей об’єкт містить подробиці про те, що сталося. +Не важливо, як ви призначаєте обробник, він отримує об'єкт події першим аргументом. Цей об'єкт містить подробиці про те, що сталося. Ми вивчимо більше про події та їх типи у наступних розділах. diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index c9c3f9bda..67202f9cf 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -39,7 +39,7 @@ 1. У самого `

`. 2. Потім зовнішнього `

`. 3. Потім зовнішнього `
`. -4. І так далі вгору до об’єкта `document`. +4. І так далі вгору до об'єкта `document`. ![](event-order-bubbling.svg) @@ -216,7 +216,7 @@ elem.addEventListener("click", e => alert(2)); - Потім обробники викликаються на самому цільовому елементі. - Потім подія спливає від `event.target` до кореня, викликаючи обробники, призначені з використанням `on`, HTML-атрибутів та `addEventListener` без третього аргументу або з третім аргументом `false/{capture:false}`. -Кожен обробник може отримати доступ до властивостей об’єкта `event`: +Кожен обробник може отримати доступ до властивостей об'єкта `event`: - `event.target` - найглибший елемент, який спричинив подію. - `event.currentTarget` (=`this`) - поточний елемент, який обробляє подію (той, на якому є обробник). diff --git a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md index c29bc8635..10b9352e9 100644 --- a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md +++ b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md @@ -14,7 +14,7 @@ Each `
` has the type in the attribute, like this:
ВікІм’яІм'я
` чи ні. +В обробнику `table.onclick` ми повинні взяти `event.target` і з'ясувати, чи був клік всередині `` чи ні. Ось покращений код: @@ -111,7 +111,7 @@ table.onclick = function(event) { Є й інші варіанти використання делегування подій. -Скажімо, ми хочемо створити меню з кнопками «Зберегти», «Завантажити», «Пошук» і так далі. А ще є об’єкт з методами `save`, `load`, `search`... Як їх поєднати? +Скажімо, ми хочемо створити меню з кнопками «Зберегти», «Завантажити», «Пошук» і так далі. А ще є об'єкт з методами `save`, `load`, `search`... Як їх поєднати? Перше, що спадає на думку -- це призначити окремий обробник кожній кнопці. Але є більш елегантне рішення. Ми можемо додати один обробник до всього меню та атрибути `data-action` до кожної кнопки відповідно до методів, які вони викликають: @@ -161,7 +161,7 @@ table.onclick = function(event) { ``` -Зауважте, що `this.onClick` прив’язаний до `this` у `(*)`. Це важливо, тому що інакше `this` в ньому посилатиметься на елемент DOM (`elem`), а не на об’єкт `Menu`, і `this[action]` буде не тим, який нам потрібен. +Зауважте, що `this.onClick` прив'язаний до `this` у `(*)`. Це важливо, тому що інакше `this` в ньому посилатиметься на елемент DOM (`elem`), а не на об'єкт `Menu`, і `this[action]` буде не тим, який нам потрібен. Отже, які переваги дає нам тут делегування? @@ -204,7 +204,7 @@ table.onclick = function(event) { Атрибутів із `data-counter` може бути скільки завгодно. Ми можемо в будь-який момент додати до HTML нові. Використовуючи делегування подій, ми фактично «розширили» HTML, додали атрибут, який описує нову поведінку. ```warn header="Завжди використовуйте метод `addEventListener` для обробників на рівні документу" -Коли ми присвоюємо обробник події об’єкту `document`, ми завжди повинні використовувати `addEventListener`, а не `document.on`, оскільки останній спричинить конфлікти: нові обробники перезапишуть старі. +Коли ми присвоюємо обробник події об'єкту `document`, ми завжди повинні використовувати `addEventListener`, а не `document.on`, оскільки останній спричинить конфлікти: нові обробники перезапишуть старі. Для реальних проєктів вважається нормальною наявність великої кількості обробників на `document`, встановлених різними частинами коду. ``` @@ -240,7 +240,7 @@ table.onclick = function(event) { Це дуже зручно -- не потрібно писати JavaScript для кожного такого елемента. Просто використовуйте поведінку. Обробник на рівні документа дозволяє працювати з будь-яким елементом сторінки. -Ми також можемо об’єднати кілька видів поведінки в одному елементі. +Ми також можемо об'єднати кілька видів поведінки в одному елементі. Шаблон «поведінка» може бути альтернативою міні-фрагментам JavaScript. @@ -259,7 +259,7 @@ table.onclick = function(event) { Переваги: ```compare -+ Спрощує ініціалізацію та економить пам’ять: не потрібно додавати багато обробників. ++ Спрощує ініціалізацію та економить пам'ять: не потрібно додавати багато обробників. + Менше коду: під час додавання або видалення елементів не потрібно додавати/видаляти обробники. + Модифікації DOM: ми можемо масово додавати/видаляти елементи за допомогою `innerHTML` тощо. ``` diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md index cc4b2fb3c..d67cd8703 100644 --- a/2-ui/2-events/04-default-browser-action/article.md +++ b/2-ui/2-events/04-default-browser-action/article.md @@ -14,7 +14,7 @@ Є два способи запобігти діям браузера: -- Основний спосіб -- це використовувати об’єкт `event`. Існує метод `event.preventDefault()`. +- Основний спосіб -- це використовувати об'єкт `event`. Існує метод `event.preventDefault()`. - Якщо обробник призначено за допомогою `on` (а не `addEventListener`), повернення `false` спрацює так само. У цьому HTML після кліку на посилання навігація не відбувається, браузер нічого не робить: @@ -94,7 +94,7 @@ menu.onclick = function(event) { ## Опція «пасивного» обробника -Необов’язковий параметр `passive: true` для `addEventListener` сигналізує браузеру, що обробник не збирається викликати `preventDefault()`. +Необов'язковий параметр `passive: true` для `addEventListener` сигналізує браузеру, що обробник не збирається викликати `preventDefault()`. Чому це може знадобитися? @@ -113,7 +113,7 @@ menu.onclick = function(event) { Є цікавий варіант використання. -Пам’ятаєте, в розділі ми говорили про `event.stopPropagation()` і чому припинення спливання -- це погано? +Пам'ятаєте, в розділі ми говорили про `event.stopPropagation()` і чому припинення спливання -- це погано? Іноді замість цього ми можемо використовувати `event.defaultPrevented`, щоб повідомити іншим обробникам, що подія була оброблена. @@ -131,7 +131,7 @@ menu.onclick = function(event) { Тепер, на додаток до цього контекстного меню, ми хотіли б реалізувати контекстне меню всього документа. -Після кліку правою кнопкою миші має з’явитися найближче контекстне меню. +Після кліку правою кнопкою миші має з'явитися найближче контекстне меню. ```html autorun height=80 no-beautify run

Правий клік, щоб відкрити контекстне меню документа

@@ -203,15 +203,15 @@ menu.onclick = function(event) { Тепер теж все працює коректно. Якщо ми маємо вкладені елементи, і кожен з них має власне контекстне меню, це також спрацює. Просто не забудьте перевірити наявність `event.defaultPrevented` у кожному обробнику `contextmenu`. ```smart header="event.stopPropagation() та event.preventDefault()" -Як ми чітко бачимо, `event.stopPropagation()` та `event.preventDefault()` (також відомий як `return false`) -- це два різні методи. Вони не пов’язані один з одним. +Як ми чітко бачимо, `event.stopPropagation()` та `event.preventDefault()` (також відомий як `return false`) -- це два різні методи. Вони не пов'язані один з одним. ``` ```smart header="Архітектура вкладених контекстних меню" -Існують також альтернативні способи реалізації вкладених контекстних меню. Один з них -- це мати єдиний глобальний об’єкт з обробником для `document.oncontextmenu`, а також методами, які дозволяють нам зберігати в ньому інші обробники. +Існують також альтернативні способи реалізації вкладених контекстних меню. Один з них -- це мати єдиний глобальний об'єкт з обробником для `document.oncontextmenu`, а також методами, які дозволяють нам зберігати в ньому інші обробники. -Об’єкт буде ловити будь-який клік правою кнопкою миші, переглядати збережені обробники та запускати відповідний. +Об'єкт буде ловити будь-який клік правою кнопкою миші, переглядати збережені обробники та запускати відповідний. -Але тоді кожен фрагмент коду, якому буде потрібно контекстне меню, повинен знати про цей об’єкт і використовувати його замість власного обробника `contextmenu`. +Але тоді кожен фрагмент коду, якому буде потрібно контекстне меню, повинен знати про цей об'єкт і використовувати його замість власного обробника `contextmenu`. ``` ## Підсумки diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md index ed36648a7..0ff3f2b5d 100644 --- a/2-ui/2-events/05-dispatch-events/article.md +++ b/2-ui/2-events/05-dispatch-events/article.md @@ -10,7 +10,7 @@ Вбудовані класи подій утворюють ієрархію, подібну до класів елементів DOM. Корінь -- це вбудований клас [Event](https://dom.spec.whatwg.org/#events). -Ми можемо створювати об’єкти `Event` на зразок цього: +Ми можемо створювати об'єкти `Event` на зразок цього: ```js let event = new Event(type[, options]); @@ -19,7 +19,7 @@ let event = new Event(type[, options]); Аргументи: - *type* -- тип події, рядок, як-от `"click"` або наш власний, наприклад, `"my-event"`. -- *options* -- об’єкт з двома необов’язковими властивостями: +- *options* -- об'єкт з двома необов'язковими властивостями: - `bubbles: true/false` -- якщо `true`, то подія спливає. - `cancelable: true/false` -- якщо `true`, то "типова дія" може бути попереджена. Пізніше ми побачимо, що це означає для користувацьких подій. @@ -27,7 +27,7 @@ let event = new Event(type[, options]); ## dispatchEvent -Після створення об’єкта події ми повинні "запустити" її на елементі за допомогою виклику `elem.dispatchEvent(event)`. +Після створення об'єкта події ми повинні "запустити" її на елементі за допомогою виклику `elem.dispatchEvent(event)`. Потім обробники реагують на неї, як на звичайну подію браузера. Якщо подія була створена з прапором `bubbles`, вона спливає. @@ -127,7 +127,7 @@ alert(event.clientX); // undefined, невідома властивість іг */!* ``` -Втім, ми можемо обійти це, призначивши `event.clientX=100` безпосередньо після створення об’єкта. Тож це питання зручності та дотримання правил. Події, створені браузером, завжди мають правильний тип. +Втім, ми можемо обійти це, призначивши `event.clientX=100` безпосередньо після створення об'єкта. Тож це питання зручності та дотримання правил. Події, створені браузером, завжди мають правильний тип. Повний опис властивостей для різних події інтерфейсу користувача є в специфікації, наприклад, [MouseEvent](https://www.w3.org/TR/uievents/#mouseevent). @@ -135,7 +135,7 @@ alert(event.clientX); // undefined, невідома властивість іг Для наших власних, абсолютно нових типів подій, таких як `"hello"`, ми повинні використовувати `new CustomEvent`. Технічно [CustomEvent](https://dom.spec.whatwg.org/#customevent) -- це те ж саме, що й `Event`, за одним винятком. -У другий аргумент (об’єкт) ми можемо додати додаткову властивість `detail` для будь-якої спеціальної інформації, яку ми хочемо передати разом із подією. +У другий аргумент (об'єкт) ми можемо додати додаткову властивість `detail` для будь-якої спеціальної інформації, яку ми хочемо передати разом із подією. Наприклад: @@ -156,7 +156,7 @@ alert(event.clientX); // undefined, невідома властивість іг ``` -Властивість `detail` може містити будь-які дані. Технічно ми могли б жити і без них, оскільки ми можемо призначити будь-які властивості звичайному об’єкту `new Event` після його створення. Але `CustomEvent` забезпечує спеціальне поле `detail`, щоб уникнути конфліктів з іншими властивостями події. +Властивість `detail` може містити будь-які дані. Технічно ми могли б жити і без них, оскільки ми можемо призначити будь-які властивості звичайному об'єкту `new Event` після його створення. Але `CustomEvent` забезпечує спеціальне поле `detail`, щоб уникнути конфліктів з іншими властивостями події. Крім того, клас події описує яка саме це подія, і якщо вона користувацька, то ми повинні використовувати `CustomEvent`, щоб явно вказати на це. @@ -272,9 +272,9 @@ alert(event.clientX); // undefined, невідома властивість іг ## Підсумки -Щоб створити подію з коду, нам спочатку потрібно створити об’єкт події. +Щоб створити подію з коду, нам спочатку потрібно створити об'єкт події. -Базовий конструктор `Event(name, options)` приймає довільне ім’я події та об’єкт параметрів із двома властивостями: +Базовий конструктор `Event(name, options)` приймає довільне ім'я події та об'єкт параметрів із двома властивостями: - `bubbles: true` якщо подія має спливати. - `cancelable: true` якщо `event.preventDefault()` повинен працювати. diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md index 22db5ea8e..9a1feb80a 100644 --- a/2-ui/3-event-details/1-mouse-events-basics/article.md +++ b/2-ui/3-event-details/1-mouse-events-basics/article.md @@ -49,7 +49,7 @@ ## Кнопка миші -Події, пов’язані з кліками, завжди мають властивість `button`, що дозволяє отримати точну кнопку миші. +Події, пов'язані з кліками, завжди мають властивість `button`, що дозволяє отримати точну кнопку миші. Зазвичай ми не використовуємо її для подій `click` і `contextmenu`, оскільки перше відбувається лише при натисканні лівою кнопкою миші, а останнє -- лише при натисканні правою кнопкою миші. diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/task.md b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/task.md index 4600761fe..565f974be 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/task.md +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/task.md @@ -6,7 +6,7 @@ importance: 5 У цьому завданні ви можете перевірити своє розуміння відразу декількох аспектів Drag'n'Drop і DOM. -Зробіть так, щоб елементи з класом `draggable` -- можна було переносити мишкою. Як м’яч в цьому розділі. +Зробіть так, щоб елементи з класом `draggable` -- можна було переносити мишкою. Як м'яч в цьому розділі. Вимоги до реалізації: diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md index 7b74bf5cb..7fa3594b0 100644 --- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md +++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md @@ -16,11 +16,11 @@ Drag'n'Drop -- відмінний спосіб поліпшити інтерфе 1. На `mousedown` -- підготувати елемент до переміщення, якщо це необхідно (наприклад, створити його клон, додати до нього клас або щось ще). 2. Потім, на `mousemove` перемістити його, змінивши значення `left/top` при позиціюванні `position: absolute`. -3. На `mouseup` -- виконати усі дії, пов’язані із завершенням перенесення. +3. На `mouseup` -- виконати усі дії, пов'язані із завершенням перенесення. Це основи. Пізніше ми розглянемо інші можливості, наприклад, підсвічування поточних елементів при перетяганні. -Ось реалізація перенесення м’яча: +Ось реалізація перенесення м'яча: ```js ball.onmousedown = function(event) { @@ -32,23 +32,23 @@ ball.onmousedown = function(event) { // щоб розташувати його відносно body document.body.append(ball); - // центруємо м’яч за координатами (pageX, pageY) + // центруємо м'яч за координатами (pageX, pageY) function moveAt(pageX, pageY) { ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; } - // переносимо наш абсолютно позиціюнованний м’яч під курсор + // переносимо наш абсолютно позиціюнованний м'яч під курсор moveAt(event.pageX, event.pageY); function onMouseMove(event) { moveAt(event.pageX, event.pageY); } - // (2) пересуваємо м’яч на mousemove + // (2) пересуваємо м'яч на mousemove document.addEventListener('mousemove', onMouseMove); - // (3) відпускаємо м’яч, видаляємо непотрібні обробники подій + // (3) відпускаємо м'яч, видаляємо непотрібні обробники подій ball.onmouseup = function() { document.removeEventListener('mousemove', onMouseMove); ball.onmouseup = null; @@ -57,14 +57,14 @@ ball.onmousedown = function(event) { }; ``` -Якщо ми запустимо код, то помітимо щось дивне. На початку `drag'n'drop` м’яч "виляє": ми починаємо перетягувати його "клон". +Якщо ми запустимо код, то помітимо щось дивне. На початку `drag'n'drop` м'яч "виляє": ми починаємо перетягувати його "клон". ```online Приклад: [iframe src="ball" height=230] -Спробуйте перенести м’яч мишкою і ви побачите вказану поведінку. +Спробуйте перенести м'яч мишкою і ви побачите вказану поведінку. ``` Все тому, що браузер має свій власний drag'n'drop, який автоматично запускається і вступає в конфлікт із нашим. Це відбувається саме для зображень та деяких інших елементів. @@ -85,32 +85,32 @@ ball.ondragstart = function() { [iframe src="ball2" height=230] ``` -Ще одна деталь -- подія `mousemove` відстежується на `document`, а не на `ball`. З першого погляду здається, що миша завжди над м’ячем і обробник `mousemove` можна повісити на сам м’яч, а не на документ. +Ще одна деталь -- подія `mousemove` відстежується на `document`, а не на `ball`. З першого погляду здається, що миша завжди над м'ячем і обробник `mousemove` можна повісити на сам м'яч, а не на документ. -Але, як ми пам’ятаємо, подія `mousemove` виникає хоч і часто, але не для кожного пікселя. Тому через швидкий рух курсору може зіскочити з м’яча і виявитися де-небудь в середині документу (або навіть за межами вікна). +Але, як ми пам'ятаємо, подія `mousemove` виникає хоч і часто, але не для кожного пікселя. Тому через швидкий рух курсору може зіскочити з м'яча і виявитися де-небудь в середині документу (або навіть за межами вікна). Ось чому ми повинні відстежувати `mousemove` на усьому `document`, щоб упіймати його у будь-якому разі. ## Правильне позиціювання -У прикладах вище м’яч позиціонується так, що його центр опиняється під курсором миші: +У прикладах вище м'яч позиціонується так, що його центр опиняється під курсором миші: ```js ball.style.left = pageX - ball.offsetWidth / 2 + 'px'; ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; ``` -Непогано, але є побічний ефект. Щоб ініціювати перенесення, ми можемо натиснути(`mousedown`) у будь-якому місці кулі. Але якщо "узяти" його з краю, то м’яч несподівано "підстрибне", щоб стати по центру під курсором миші. +Непогано, але є побічний ефект. Щоб ініціювати перенесення, ми можемо натиснути(`mousedown`) у будь-якому місці кулі. Але якщо "узяти" його з краю, то м'яч несподівано "підстрибне", щоб стати по центру під курсором миші. Було б краще, якби ми зберігали початковий зсув елементу відносно курсору. -Наприклад, якщо ми "схопили" за край м’яча, то курсор повинен залишатися над краєм під час перенесення. +Наприклад, якщо ми "схопили" за край м'яча, то курсор повинен залишатися над краєм під час перенесення. ![](ball_shift.svg) Давайте покращимо наш алгоритм: -1. Коли користувач натискає на м’ячик (`mousedown`) - запам’ятаємо відстань від курсора миші до лівого верхнього кута м’яча в змінних `shiftX/shiftY`. Далі утримуватимемо цю відстань при пересуванні м’яча. +1. Коли користувач натискає на м'ячик (`mousedown`) - запам'ятаємо відстань від курсора миші до лівого верхнього кута м'яча в змінних `shiftX/shiftY`. Далі утримуватимемо цю відстань при пересуванні м'яча. Щоб отримати цей зсув, ми можемо відняти координати: @@ -120,11 +120,11 @@ ball.style.top = pageY - ball.offsetHeight / 2 + 'px'; let shiftY = event.clientY - ball.getBoundingClientRect().top; ``` -2. Далі при перенесенні м’яча ми позиціонуємо його з тим же зсувом відносно курсора миші, таким чином: +2. Далі при перенесенні м'яча ми позиціонуємо його з тим же зсувом відносно курсора миші, таким чином: ```js // onmousemove - // м’яч має position:absolute + // м'яч має position:absolute ball.style.left = event.pageX - *!*shiftX*/!* + 'px'; ball.style.top = event.pageY - *!*shiftY*/!* + 'px'; ``` @@ -145,7 +145,7 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); - // переносимо м’яч на координати (pageX, pageY) + // переносимо м'яч на координати (pageX, pageY) // додатково враховуючи початковий зсув відносно курсору миші function moveAt(pageX, pageY) { ball.style.left = pageX - *!*shiftX*/!* + 'px'; @@ -156,10 +156,10 @@ ball.onmousedown = function(event) { moveAt(event.pageX, event.pageY); } - // пересуваємо м’яч при mousemove + // пересуваємо м'яч при mousemove document.addEventListener('mousemove', onMouseMove); - // відпускаємо м’яч, видаляємо непотрібні обробники подій + // відпускаємо м'яч, видаляємо непотрібні обробники подій ball.onmouseup = function() { document.removeEventListener('mousemove', onMouseMove); ball.onmouseup = null; @@ -178,11 +178,11 @@ ball.ondragstart = function() { [iframe src="ball3" height=230] ``` -Відмінність особливо помітна, якщо захопити м’яч за правий нижній кут. У попередньому прикладі м’ячик "стрибне" серединою під курсор, а в цьому -- плавно переноситиметься з поточної позиції. +Відмінність особливо помітна, якщо захопити м'яч за правий нижній кут. У попередньому прикладі м'ячик "стрибне" серединою під курсор, а в цьому -- плавно переноситиметься з поточної позиції. ## Цілі перенесення (droppables) -У попередніх прикладах м’яч можна було кинути просто де завгодно в межах вікна. На практиці ми зазвичай беремо один елемент і перетягуємо в іншій. Наприклад, "файл" в "папку" або щось ще. +У попередніх прикладах м'яч можна було кинути просто де завгодно в межах вікна. На практиці ми зазвичай беремо один елемент і перетягуємо в іншій. Наприклад, "файл" в "папку" або щось ще. Абстрактно кажучи, ми беремо перетягуваний (draggable) елемент і поміщаємо його в інший елемент -- "ціль перенесення" (droppable). @@ -213,7 +213,7 @@ ball.ondragstart = function() {
``` -Те ж саме з перетягуючим елементом. М’яч завжди знаходиться поверх інших елементів, тому події спрацьовують на ньому. Які б обробники ми не встановили на нижні елементи, вони не будуть виконані. +Те ж саме з перетягуючим елементом. М'яч завжди знаходиться поверх інших елементів, тому події спрацьовують на ньому. Які б обробники ми не встановили на нижні елементи, вони не будуть виконані. Ось чому початкова ідея встановити обробники на потенційні цілі перенесення не спрацює на практиці. Обробники не будуть викликатися. @@ -221,19 +221,19 @@ ball.ondragstart = function() { Існує метод `document.elementFromPoint(clientX, clientY)`. Він повертає найбільш глибоко вкладений елемент за заданими координатами вікна (або `null`, якщо зазначені координати знаходяться за межами вікна). Якщо в одних і тих самих координатах є кілька елементів, що перекриваються, повертається найвищий. -Ми можемо використати його, щоб з будь-якого обробника подій миші з’ясувати, над якою ми потенційною ціллю перенесення, ось так: +Ми можемо використати його, щоб з будь-якого обробника подій миші з'ясувати, над якою ми потенційною ціллю перенесення, ось так: ```js // всередині обробника події миші ball.hidden = true; // (*) ховаємо елемент який переносимо let elemBelow = document.elementFromPoint(event.clientX, event.clientY); -// elemBelow -- елемент під м’ячем (можлива ціль перенесення) +// elemBelow -- елемент під м'ячем (можлива ціль перенесення) ball.hidden = false; ``` -Зауважимо, нам потрібно заховати м’яч перед викликом функції `(*)`. В іншому випадку за цими координатами ми будемо отримувати м’яч, адже це і є елемент безпосередньо під курсором: `elemBelow=ball`. Так що ми ховаємо його і одразу показуємо. +Зауважимо, нам потрібно заховати м'яч перед викликом функції `(*)`. В іншому випадку за цими координатами ми будемо отримувати м'яч, адже це і є елемент безпосередньо під курсором: `elemBelow=ball`. Так що ми ховаємо його і одразу показуємо. Ми можемо використовувати цей код для перевірки того, над яким елементом ми "летимо", в будь-який час. І обробити закінчення перенесення, коли воно станеться. @@ -250,7 +250,7 @@ function onMouseMove(event) { let elemBelow = document.elementFromPoint(event.clientX, event.clientY); ball.hidden = false; - // подія mousemove може статися і коли курсор за межами вікна (м’яч перетягнули за межі екрану) + // подія mousemove може статися і коли курсор за межами вікна (м'яч перетягнули за межі екрану) // якщо clientX/clientY за межами вікна, elementFromPoint поверне null if (!elemBelow) return; @@ -276,7 +276,7 @@ function onMouseMove(event) { } ``` -У наведеному нижче прикладі, коли м’яч перетягується через футбольні ворота, ворота підсвічуються. +У наведеному нижче прикладі, коли м'яч перетягується через футбольні ворота, ворота підсвічуються. [codetabs height=250 src="ball4"] @@ -289,7 +289,7 @@ function onMouseMove(event) { Ключові ідеї: 1. Потік подій: `ball.mousedown` -> `document.mousemove` -> `ball.mouseup` (не забудьте скасувати браузерний `ondragstart`). -2. На початку перетягування -- запам’ятовуємо початкове зміщення курсору щодо елемента: `shiftX/shiftY` і зберігаємо його при перетягуванні. +2. На початку перетягування -- запам'ятовуємо початкове зміщення курсору щодо елемента: `shiftX/shiftY` і зберігаємо його при перетягуванні. 3. Виявляємо потенційні цілі перенесення під курсором за допомогою `document.elementFromPoint`. На цій основі можна зробити багато чого. diff --git a/2-ui/3-event-details/6-pointer-events/article.md b/2-ui/3-event-details/6-pointer-events/article.md index 504c5e8cc..8d0f55a59 100644 --- a/2-ui/3-event-details/6-pointer-events/article.md +++ b/2-ui/3-event-details/6-pointer-events/article.md @@ -16,7 +16,7 @@ Але все-таки цього було недостатньо, оскільки є багато інших пристроїв, наприклад ручок, які мають свої особливості. Крім того, код, який прослуховує як події дотику, так і миші, досить громіздкий. -- Щоб розв’язати ці проблеми, було введено новий стандарт Pointer Events. Він забезпечує єдиний набір подій для всіх видів вказівних пристроїв. +- Щоб розв'язати ці проблеми, було введено новий стандарт Pointer Events. Він забезпечує єдиний набір подій для всіх видів вказівних пристроїв. На цей час специфікація [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) підтримується в усіх основних браузерах, тоді як новіша версія [Pointer Events Level 3](https://w3c.github.io/pointerevents/) знаходиться в розробці і в основному сумісна з Pointer Events другого рівня. @@ -88,7 +88,7 @@ Зверніть увагу: `pointerId` призначається не всьому пристрою, а кожному дотику пальця. Якщо ми використовуємо 5 пальців, щоб одночасно торкнутися екрана, у нас буде 5 подій `pointerdown`, кожна зі своїми відповідними координатами та іншим `pointerId`. -Події, пов’язані з першим пальцем, завжди мають значення `isPrimary=true`. +Події, пов'язані з першим пальцем, завжди мають значення `isPrimary=true`. Ми можемо відстежувати кілька пальців, використовуючи їх `pointerId`. Коли користувач рухає, а потім прибирає палець, ми отримуємо події `pointermove` та `pointerup` з тим же `pointerId`, що й у `pointerdown`. @@ -111,7 +111,7 @@ Ми продемонструємо `pointercancel` на практичному прикладі, щоб побачити, як він впливає на нас. -Скажімо, ми впроваджуємо drag'n'drop для м’яча, як на початку статті . +Скажімо, ми впроваджуємо drag'n'drop для м'яча, як на початку статті . Ось хід дій користувача та відповідні події: @@ -120,7 +120,7 @@ 2) Потім він починає рухати вказівник (перетягуючи таким чином зображення) - `pointermove` спрацьовує, можливо, кілька разів 3) І тоді відбувається сюрприз! Браузер має вбудовану підтримку drag'n'drop для зображень, яка запускається та бере на себе процес drag'n'drop, таким чином генеруючи подію `pointercancel`. - - Тепер браузер самостійно обробляє перетягування зображення. Користувач може навіть перетягнути зображення м’яча з браузера, у свою поштову програму або файловий менеджер. + - Тепер браузер самостійно обробляє перетягування зображення. Користувач може навіть перетягнути зображення м'яча з браузера, у свою поштову програму або файловий менеджер. - Для нас більше немає подій `pointermove`. Таким чином, проблема полягає в тому, що браузер "викрадає" взаємодію: `pointercancel` запускається на початку процесу "перетягування" і події `pointermove` більше не генеруються. @@ -140,7 +140,7 @@ 1. Запобігти нативному drag'n'drop: - Ми можемо зробити це, встановивши `ball.ondragstart = () => false`, як описано в статті . - Це добре працює для подій миші. -2. Для сенсорних пристроїв існують інші дії браузера, пов’язані з дотиком (крім перетягування). Щоб уникнути проблем і з ними: +2. Для сенсорних пристроїв існують інші дії браузера, пов'язані з дотиком (крім перетягування). Щоб уникнути проблем і з ними: - Запобігти їм, встановивши `#ball { touch-action: none }` у CSS - Тоді наш код почне працювати на сенсорних пристроях. @@ -154,7 +154,7 @@ Як бачите, `pointercancel` більше немає. ``` -Тепер ми можемо додати код для фактичного переміщення м’яча, і наш drag'n'drop працюватиме для пристроїв миші та сенсорних пристроїв. +Тепер ми можемо додати код для фактичного переміщення м'яча, і наш drag'n'drop працюватиме для пристроїв миші та сенсорних пристроїв. ## Захоплення вказівника @@ -163,11 +163,11 @@ Ідея дуже проста, але спочатку може здатися досить дивною, оскільки нічого подібного для будь-якого іншого типу події не існує. Основним методом є: -- `elem.setPointerCapture(pointerId)` -- зв’язує події із заданим `pointerId` з `elem`. Після виклику всі події вказівника з однаковим `pointerId` матимуть `elem` як ціль (ніби вони відбулися на `elem`), незалежно від того, де в документі вони дійсно відбулися. +- `elem.setPointerCapture(pointerId)` -- зв'язує події із заданим `pointerId` з `elem`. Після виклику всі події вказівника з однаковим `pointerId` матимуть `elem` як ціль (ніби вони відбулися на `elem`), незалежно від того, де в документі вони дійсно відбулися. Іншими словами, `elem.setPointerCapture(pointerId)` перенацілює всі наступні події з заданим `pointerId` на `elem`. -Прив’язка усувається: +Прив'язка усувається: - автоматично, коли відбуваються події `pointerup` або `pointercancel`, - автоматично, коли `elem` видаляється з документа, - коли викликається `elem.releasePointerCapture(pointerId)`. @@ -200,15 +200,15 @@ У рішенні на основі подій миші, щоб відстежувати всі рухи вказівника, включно з тим, коли він переміщується вище/нижче `thumb`, ми повинні були призначити обробник події `mousemove` для всього `document`. -Однак це не "найчистіше" рішення. Одна з проблем полягає в тому, що коли користувач переміщує вказівник по документу, він може запускати обробники подій (наприклад, `mouseover`) на деяких інших елементах, викликати абсолютно не пов’язані функції інтерфейсу користувача, а ми цього не хочемо. +Однак це не "найчистіше" рішення. Одна з проблем полягає в тому, що коли користувач переміщує вказівник по документу, він може запускати обробники подій (наприклад, `mouseover`) на деяких інших елементах, викликати абсолютно не пов'язані функції інтерфейсу користувача, а ми цього не хочемо. Це місце, де `setPointerCapture` вступає в гру. - Ми можемо викликати `thumb.setPointerCapture(event.pointerId)` в обробнику `pointerdown`, - Тоді майбутні події вказівника до `pointerup/cancel` будуть перенацілені на `thumb`. -- Коли відбувається `pointerup` (перетягування завершено), прив’язка видаляється автоматично, нам не потрібно перейматись за це. +- Коли відбувається `pointerup` (перетягування завершено), прив'язка видаляється автоматично, нам не потрібно перейматись за це. -Тому, навіть якщо користувач переміщує вказівник по всьому документу, обробники подій будуть викликатися на `thumb`. Проте, властивості координат об’єктів події, такі як `clientX/clientY`, залишаться правильними - захоплення впливає лише на `target/currentTarget`. +Тому, навіть якщо користувач переміщує вказівник по всьому документу, обробники подій будуть викликатися на `thumb`. Проте, властивості координат об'єктів події, такі як `clientX/clientY`, залишаться правильними - захоплення впливає лише на `target/currentTarget`. Ось основний код: @@ -253,14 +253,14 @@ thumb.onpointerdown = function(event) { Зрештою, захоплення вказівника дає нам дві переваги: -1. Код стає чистішим, оскільки нам більше не потрібно додавати/видаляти обробники всього `document`. Прив’язка прибирається автоматично.. +1. Код стає чистішим, оскільки нам більше не потрібно додавати/видаляти обробники всього `document`. Прив'язка прибирається автоматично.. 2. Якщо в документі є інші обробники подій вказівника, вони не будуть випадково ініційовані вказівником, коли користувач перетягує повзунок. ### Події захоплення вказівника Тут для повноти слід згадати ще одну річ. -Існують дві події, пов’язані із захопленням вказівника: +Існують дві події, пов'язані із захопленням вказівника: - `gotpointercapture` спрацьовує, коли елемент використовує `setPointerCapture` для включення захоплення. - `lostpointercapture` запускається, коли відбувається звільнення від захоплення: або явно за допомогою виклику `releasePointerCapture`, або автоматично під час `pointerup`/`pointercancel`. diff --git a/2-ui/3-event-details/7-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md index d6623732e..0eae2efde 100644 --- a/2-ui/3-event-details/7-keyboard-events/article.md +++ b/2-ui/3-event-details/7-keyboard-events/article.md @@ -28,7 +28,7 @@ ### event.code та event.key -Властивість `key` об’єкта події дозволяє отримати символ, а властивість `code` об’єкта події дозволяє отримати "фізичний код клавіші". +Властивість `key` об'єкта події дозволяє отримати символ, а властивість `code` об'єкта події дозволяє отримати "фізичний код клавіші". Наприклад, ту саму клавішу `key:Z` можна натискати з або без клавіші `key:Shift`. Це дає нам два різних символи: малий `z` і великий `Z`. @@ -107,7 +107,7 @@ document.addEventListener('keydown', function(event) { Для надійного відстеження символів, що залежать від розкладки, `event.key` може бути кращим рішенням. -З іншого боку, `event.code` має перевагу, бо залишається завжди однаковим, прив’язаним до місця розташування фізичної клавіші, навіть якщо відвідувач змінює мову. Тому гарячі клавіші, які покладаються на нього, працюють добре навіть у разі перемикання мови. +З іншого боку, `event.code` має перевагу, бо залишається завжди однаковим, прив'язаним до місця розташування фізичної клавіші, навіть якщо відвідувач змінює мову. Тому гарячі клавіші, які покладаються на нього, працюють добре навіть у разі перемикання мови. Чи хочемо ми обробляти клавіші, що залежать від розкладки? Тоді `event.key` -- це вихід. @@ -117,7 +117,7 @@ document.addEventListener('keydown', function(event) { Якщо клавіша натискається досить довго, вона починає автоматично повторюватися: `keydown` запускається знову і знову, а потім, коли вона відпускається, ми нарешті отримуємо `keyup`. Таким чином, це нормально мати багато `keydown` і один `keyup`. -Для подій, ініційованих автоповтором, об’єкт події має властивість `event.repeat`, встановлену на `true`. +Для подій, ініційованих автоповтором, об'єкт події має властивість `event.repeat`, встановлену на `true`. ## Типові дії @@ -126,7 +126,7 @@ document.addEventListener('keydown', function(event) { Наприклад: -- На екрані з’являється символ (найбільш очевидний результат). +- На екрані з'являється символ (найбільш очевидний результат). - Символ видалено (`key:Delete` клавіша). - Сторінка прокручується (`key:PageDown` клавіша). - Браузер відкриває діалогове вікно "Зберегти сторінку". (`key:Ctrl+S`) @@ -147,7 +147,7 @@ function checkPhoneKey(key) { Обробник `onkeydown` використовує тут `checkPhoneKey` для перевірки натиснення клавіші. Якщо вона валідна (від `0..9` або з `+-()`), обробник повертає `true`, інакше `false`. -Як ми знаємо, значення `false`, що повертається з обробника подій та присвоєне за допомогою властивості DOM або атрибута, як-от вище, запобігає типовій дії. Саме тому для клавіш, які не проходять тест, у `` нічого не з’являється. (Повернуте значення `true` ні на що не впливає, має значення лише повернення `false`) +Як ми знаємо, значення `false`, що повертається з обробника подій та присвоєне за допомогою властивості DOM або атрибута, як-от вище, запобігає типовій дії. Саме тому для клавіш, які не проходять тест, у `` нічого не з'являється. (Повернуте значення `true` ні на що не впливає, має значення лише повернення `false`) Зверніть увагу, що спеціальні клавіші, такі як `key:Backspace`, `key:Left`, `key:Right`, не працюють у полі для введення. Це побічний ефект суворого фільтра `checkPhoneKey`. Ці клавіші змушують її повертати `false`. @@ -171,7 +171,7 @@ function checkPhoneKey(key) { ## Застарілий код -У минулому була подія `keypress`, а також `keyCode`, `charCode`, `which` властивості об’єкта події. +У минулому була подія `keypress`, а також `keyCode`, `charCode`, `which` властивості об'єкта події. Під час роботи з ними було так багато несумісностей у браузерах, що у розробників специфікації не було іншого виходу, окрім як відмовитися від усіх них і створити нові, сучасні події (описані вище в цьому розділі). Старий код все ще працює, оскільки браузери продовжують підтримувати його, але більше немає потреби використовувати його. diff --git a/2-ui/3-event-details/8-onscroll/2-updown-button/task.md b/2-ui/3-event-details/8-onscroll/2-updown-button/task.md index e533fcf63..eabfdaddd 100644 --- a/2-ui/3-event-details/8-onscroll/2-updown-button/task.md +++ b/2-ui/3-event-details/8-onscroll/2-updown-button/task.md @@ -8,7 +8,7 @@ importance: 5 Вона має працювати так: - Поки сторінка не прокручена принаймні на висоту вікна -- вона невидима. -- Якщо сторінка прокручена нижче висоти вікна, у верхньому лівому куті з’являється стрілка "вгору". Якщо сторінку прокрутити назад, вона зникне. +- Якщо сторінка прокручена нижче висоти вікна, у верхньому лівому куті з'являється стрілка "вгору". Якщо сторінку прокрутити назад, вона зникне. - При натисканні стрілки сторінка прокручується вгору. Ось так (верхній лівий кут, прокрутіть, щоб побачити): diff --git a/2-ui/3-event-details/8-onscroll/3-load-visible-img/task.md b/2-ui/3-event-details/8-onscroll/3-load-visible-img/task.md index a5cb5983e..2b98165df 100644 --- a/2-ui/3-event-details/8-onscroll/3-load-visible-img/task.md +++ b/2-ui/3-event-details/8-onscroll/3-load-visible-img/task.md @@ -4,7 +4,7 @@ importance: 4 # Завантаження видимих зображень -Припустимо, у нас є клієнт з низькою швидкістю з’єднання, і ми хочемо заощадити його мобільний трафік. +Припустимо, у нас є клієнт з низькою швидкістю з'єднання, і ми хочемо заощадити його мобільний трафік. З цією метою ми вирішуємо не показувати зображення відразу, а замінити їх заповнювачами, наприклад: diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md index 50e0ceef8..2bde342af 100644 --- a/2-ui/4-forms-controls/1-form-elements/article.md +++ b/2-ui/4-forms-controls/1-form-elements/article.md @@ -8,7 +8,7 @@ Форми в документі є членами спеціальної колекції `document.forms`. -Це так звана *"іменована колекція"*: щоб отримати форму ми можемо використовувати як її ім’я, так і порядковий номер у документі. +Це так звана *"іменована колекція"*: щоб отримати форму ми можемо використовувати як її ім'я, так і порядковий номер у документі. ```js no-beautify document.forms.my; // форма з іменем "my" (name="my") @@ -36,7 +36,7 @@ document.forms[0]; // перша форма в документі ``` -У колекції може бути кілька елементів з однаковим ім’ям (`name`). Це типово для перемикачів (radio buttons) та чекбоксів (checkboxes). +У колекції може бути кілька елементів з однаковим ім'ям (`name`). Це типово для перемикачів (radio buttons) та чекбоксів (checkboxes). В такому випадку `form.elements[name]` -- це *колекція*. Наприклад: @@ -94,7 +94,7 @@ alert(ageElems[0]); // [object HTMLInputElement] Іншими словами, замість `form.elements.login` ми можемо написати `form.login`. -Такий варіант також працює, але є незначна проблема: якщо ми отримуємо доступ до елемента, а потім змінюємо його ім’я (`name`), то він все ще буде доступний під старим ім’ям (а також під новим). +Такий варіант також працює, але є незначна проблема: якщо ми отримуємо доступ до елемента, а потім змінюємо його ім'я (`name`), то він все ще буде доступний під старим ім'ям (а також під новим). Це легко побачити на прикладі: @@ -106,9 +106,9 @@ alert(ageElems[0]); // [object HTMLInputElement] ``` -Усередині iframe можуть бути інші iframe. Відповідні об’єкти `window` утворюють ієрархію. +Усередині iframe можуть бути інші iframe. Відповідні об'єкти `window` утворюють ієрархію. Навігаційні посилання: @@ -228,7 +228,7 @@ if (window == top) { // current window == window.top? Ось список обмежень: `allow-same-origin` -: Типово атрибут `"sandbox"` нав’язує політику "іншого походження" для iframe. Це змушує браузер сприймати `iframe`, як iframe з іншим походженням, навіть якщо його `src` вказує на той самий сайт. Це застосовує усі неявні обмеженнями для скриптів. Цей параметр вимикає цю функцію. +: Типово атрибут `"sandbox"` нав'язує політику "іншого походження" для iframe. Це змушує браузер сприймати `iframe`, як iframe з іншим походженням, навіть якщо його `src` вказує на той самий сайт. Це застосовує усі неявні обмеженнями для скриптів. Цей параметр вимикає цю функцію. `allow-top-navigation` : Дозволяє `iframe` змінити `parent.location`. @@ -270,12 +270,12 @@ if (window == top) { // current window == window.top? Аргументи: `data` -: Дані для відправки. Можуть бути будь-яким об’єктом, дані клонуються за допомогою "алгоритму структурованої серіалізації". IE підтримує лише рядки, тому ми повинні застосувати `JSON.stringify` для складних об’єктів для підтримки цього браузера. +: Дані для відправки. Можуть бути будь-яким об'єктом, дані клонуються за допомогою "алгоритму структурованої серіалізації". IE підтримує лише рядки, тому ми повинні застосувати `JSON.stringify` для складних об'єктів для підтримки цього браузера. `targetOrigin` : Вказує джерело для цільового вікна, щоб повідомлення отримувало лише вікно з даного джерела. -`targetOrigin` є заходом безпеки. Пам’ятайте, якщо цільове вікно походить з іншого джерела, ми не можемо прочитати його `location` у вікні відправника. Тому ми не можемо бути впевнені, який сайт зараз відкритий у передбачуваному вікні: користувач міг би піти, а вікно відправника не має про це поняття. +`targetOrigin` є заходом безпеки. Пам'ятайте, якщо цільове вікно походить з іншого джерела, ми не можемо прочитати його `location` у вікні відправника. Тому ми не можемо бути впевнені, який сайт зараз відкритий у передбачуваному вікні: користувач міг би піти, а вікно відправника не має про це поняття. `targetOrigin` гарантує, що iframe отримає дані, лише якщо він все ще знаходиться на потрібному сайті. Це важливо, коли дані є чутливими або конфіденційними. @@ -310,7 +310,7 @@ if (window == top) { // current window == window.top? Щоб отримати повідомлення, вікно отримувач має мати обробник події `message`. Він запускається, коли викликається `postMessage` (і перевірка `targetOrigin` успішна). -Об’єкт події має спеціальні властивості: +Об'єкт події має спеціальні властивості: `data` : Дані від `postMessage`. @@ -351,7 +351,7 @@ window.addEventListener("message", function(event) { - Зі спливаючого вікна: `window.opener` -- це посилання на основне вікно зі спливаючого вікна. Для iframes ми можемо отримати доступ до батьківських/дочірніх вікон за допомогою: -- `window.frames` -- набір вкладених об’єктів вікна, +- `window.frames` -- набір вкладених об'єктів вікна, - `window.parent`, `window.top` посилання на батьківське та верхнє вікна, - `iframe.contentWindow` -- вікно всередині тегу `