Skip to content

fix(2-1.4): Review Searching: getElement*, querySelector* article #529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions 2-ui/1-document/04-searching-elements-dom/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

Властивості навігації по DOM чудові, коли елементи розташовані близько один до одного. А якщо ні? Як отримати довільний елемент сторінки?

Для цього існують додаткові методи пошуку.
Для цього в DOM існують додаткові методи пошуку.

## document.getElementById або просто id

Якщо елемент має атрибут `id`, ми можемо отримати його за допомогою методу `document.getElementById(id)`, незалежно від того, де він знаходиться.
Якщо елемент має атрибут `id`, ми можемо отримати його викликом `document.getElementById(id)`, незалежно від того, де він знаходиться.

Наприклад:

Expand Down Expand Up @@ -42,7 +42,7 @@
</script>
```

...Але це лише якщо ми не оголошуємо змінну JavaScript з тим самим ім’ям, інакше вона матиме пріоритет:
...Але це лише якщо ми не оголосили змінну JavaScript з таким же ім’ям, інакше вона матиме пріоритет:

```html run untrusted height=0
<div id="elem"></div>
Expand All @@ -57,28 +57,28 @@
```warn header="Будь ласка, не використовуйте id-іменовані глобальні змінні для доступу до елементів"
Ця поведінка описана [у специфікації](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem), тож це свого роду стандарт. Але він підтримується в основному для сумісності.

Браузер намагається нам допомогти, змішуючи простори імен JS і DOM. Це добре для простих сценаріїв, вбудованих у HTML, але загалом це не дуже добре. Можуть виникнути конфлікти імен. Крім того, коли хтось читає JS-код і не бачить HTML, незрозуміло, звідки приходить змінна.
Браузер намагається нам допомогти, змішуючи простори імен JS і DOM. Це зручно для простих скриптів, які знаходяться прямо в HTML, але загалом це не дуже добре. Можуть виникнути конфлікти імен. Крім того, коли хтось читає JS-код і не бачить HTML, незрозуміло, звідки приходить змінна.

Тут у підручнику ми використовуємо `id` для прямого посилання на елемент для стислості, коли очевидно, звідки цей елемент походить.
У цьому посібнику ми будемо використовувати `id` для прямого посилання на елемент для стислості, коли очевидно, звідки цей елемент походить.

У реальному житті краще надавати перевагу `document.getElementById`.
У реальному житті краще використовувати `document.getElementById`.
```

```smart header="`id` має бути унікальним"
`id` має бути унікальним. У документі може бути лише один елемент із заданим `id`.
```smart header="Значення `id` має бути унікальним"
Значення `id` має бути унікальним. У документі повинен бути лише один елемент із заданим `id`.

Якщо є кілька елементів з однаковим `id`, то поведінка методів, які його використовують, буде непередбачуваною, наприклад. `document.getElementById` може повертати будь-який з таких елементів випадковим чином. Тому, будь ласка, дотримуйтеся правила та залишайте `id` унікальним.
Якщо є кілька елементів з однаковим `id`, то поведінка методів, які його використовують є непередбачуваною. Наприклад, `document.getElementById` може повертати будь-який з таких елементів випадковим чином. Тому, будь ласка, дотримуйтеся правила та залишайте `id` унікальним.
```

```warn header="Лише `document.getElementById`, а не `anyElem.getElementById`"
Метод `getElementById` можна викликати лише для об’єкта `document`. Він шукає вказаний `id` у всьому документі.
Метод `getElementById` може бути викликаний лише на об’єкті `document`. Він шукає вказаний `id` у всьому документі.
```

## querySelectorAll [#querySelectorAll]

До сьогодні найуніверсальніший метод -- це `elem.querySelectorAll(css)`, він повертає всі елементи всередині `elem`, що відповідають заданому CSS-селектору.
Найбільш гнучким методом є `elem.querySelectorAll(css)`, який повертає всі елементи всередині `elem`, що відповідають заданому CSS-селектору.

Тут ми шукаємо всі елементи `<li>`, які є останніми дочірніми:
Тут ми шукаємо всі елементи `<li>`, які є останніми дочірніми елементами:

```html run
<ul>
Expand All @@ -103,22 +103,22 @@
Цей метод дійсно потужний, оскільки можна використовувати будь-який CSS-селектор.

```smart header="Також можна використовувати псевдокласи"
Псевдокласи в CSS-селекторі, такі як `:hover` і `:active`, також підтримуються. Наприклад, `document.querySelectorAll(':hover')` поверне колекцію елементів, що знаходяться під курсором миші (у порядку вкладення: від крайнього `<html>` до найбільш вкладеного).
Псевдокласи в CSS-селекторі, такі як `:hover` і `:active`, також підтримуються. Наприклад, `document.querySelectorAll(':hover')` поверне колекцію елементів, що знаходяться під курсором миші (у порядку вкладення: від зовнішнього `<html>` до найбільш вкладеного).
```

## querySelector [#querySelector]

Виклик `elem.querySelector(css)` повертає перший елемент, що відповідає даному CSS-селектору.

Іншими словами, результат такий самий, як і `elem.querySelectorAll(css)[0]`, але останній шукає *всі* елементи та вибирає один, а `elem.querySelector` просто шукає один. Тому його писати швидше і коротше.
Іншими словами, результат такий самий, як і `elem.querySelectorAll(css)[0]`, але він спочатку знайде всі елементи, а потім візьме перший, тоді як `elem.querySelector` знайде лише перший та зупиниться. Цей метод не лише прискорює виконання, а й дозволяє скоротити кількість написаного коду.

## matches

Попередні методи виконували пошук по DOM.

[elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches) нічого не шукає, він просто перевіряє, чи відповідає `elem` заданому CSS-селектору. Він повертає `true` або `false`.
Метод [elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches) нічого не шукає, він просто перевіряє, чи відповідає `elem` заданому CSS-селектору. Він повертає `true` або `false`.

Цей метод стає в пригоді, коли ми перебираємо елементи (наприклад, у масиві чи чомусь подібному) і намагаємося відфільтрувати ті, які нас цікавлять.
Цей метод стає в нагоді, коли ми перебираємо елементи (наприклад, у масиві чи чомусь подібному) і намагаємося відфільтрувати ті, які нас цікавлять.

Наприклад:

Expand All @@ -144,7 +144,7 @@

Метод `elem.closest(css)` шукає найближчого предка, який відповідає CSS-селектору. Сам `elem` також включається в пошук.

Іншими словами, метод `closest` підіймається від елемента і перевіряє кожного з батьків. Якщо він збігається з селектором, пошук припиняється, і повертається предок.
Іншими словами, метод `closest` йде вгору від елемента і перевіряє кожного з батьківських елементів. Якщо він відповідає заданому селектору, пошук припиняється, і повертається знайдений предок.

Наприклад:

Expand Down Expand Up @@ -174,10 +174,10 @@

Сьогодні вони здебільшого історичні, оскільки `querySelector` є потужнішим і коротшим для написання.

Тому тут ми розглянемо їх переважно для повноти, тоді як ви все ще можете знайти їх у старому коді.
Тому тут ми розглянемо їх переважно для повноти, тоді як ви все ще можете знайти їх у старих скриптах.

- `elem.getElementsByTagName(tag)` шукає елементи з заданим тегом і повертає їх колекцію. Параметр `tag` також може бути зірочкою `"*"` для "будь-яких тегів".
- `elem.getElementsByClassName(className)` повертає елементи, які мають заданий CSS-клас.
- `elem.getElementsByTagName(tag)` шукає елементи з заданим тегом і повертає колекцію цих елементів. Параметр `tag` також може бути зірочкою `"*"` для "будь-яких тегів".
- `elem.getElementsByClassName(className)` повертає елементи, які мають вказаний CSS-клас.
- `document.getElementsByName(name)` повертає елементи з заданим атрибутом `name` для всього документа. Використовується дуже рідко.

Наприклад:
Expand Down Expand Up @@ -219,9 +219,9 @@ let divs = document.getElementsByTagName('div');
```

```warn header="Не забуваємо про літеру `\"s\"`!"
Розробники початківці іноді забувають про літеру `"s"`. Тобто вони намагаються викликати `getElementByTagName` замість <code>getElement<b>s</b>ByTagName</code>.
У новачків у розробці іноді трапляються випадки, коли вони забувають про літеру `"s"`. Тобто вони намагаються викликати метод `getElementByTagName` замість <code>getElement<b>s</b>ByTagName</code>.

Літера `"s"` відсутня в `getElementById`, оскільки повертає один елемент. Але `getElementsByTagName` повертає колекцію елементів, тому всередині є `"s"`.
Літера `"s"` відсутня в назві методу `getElementById`, оскільки він повертає один елемент. А `getElementsByTagName` повертає колекцію елементів, тому всередині є `"s"`.
```

````warn header="Повертає колекцію, а не елемент!"
Expand Down Expand Up @@ -363,12 +363,12 @@ document.getElementsByTagName('input')[0].value = 5;
</tbody>
</table>

Найчастіше використовуються `querySelector` і `querySelectorAll`, але `getElement(s)By*` може бути корисним час від часу або знаходитися в старому коді.
Найчастіше використовуються `querySelector` і `querySelectorAll`, але `getElement(s)By*` може бути корисним час від часу або зустрічатися в старих скриптах.

Крім того:

- `elem.matches(css)` існує для того, щоб перевірити, чи відповідає `elem` заданому CSS-селектору.
- `elem.closest(css)` існує для того, щоб шукати найближчого предка, який відповідає заданому CSS-селектору. Сам `elem` також перевіряється.
- Існує метод `elem.matches(css)` , який перевіряє, чи відповідає `elem` заданому CSS-селектору.
- Існує метод `elem.closest(css)` , який шукає найближчого предка, який відповідає заданому CSS-селектору. Сам `elem` також перевіряється.

І згадаймо тут ще один метод перевірки взаємовідносин нащадок-предок, оскільки він іноді стає в нагоді:
- `elemA.contains(elemB)` повертає true, якщо `elemB` знаходиться всередині `elemA` (нащадок `elemA`) або коли `elemA==elemB`.