JS метод Document.normalize()


Загальний опис

Метод document.normalize() використовується для нормалізації дерева вузлів документа, видаляючи порожні текстові вузли та об'єднуючи суміжні текстові вузли. Цей метод може бути корисним для оптимізації та спрощення структури DOM, особливо після маніпуляцій з вузлами, таких як додавання або видалення елементів. Нормалізація може покращити продуктивність та полегшити роботу з DOM.

Використання document.normalize() досить просте – потрібно лише викликати цей метод на об'єкті document або на будь-якому вузлі документа, який необхідно нормалізувати. Наприклад:

document.normalize();

Це нормалізує все дерево документа, видаливши порожні текстові вузли та об'єднавши суміжні текстові вузли.

Розглянемо більш детальний приклад використання document.normalize(). Припустимо, ми маємо таку HTML-структуру:

<div id="content">
  <p>Привіт,</p>
  <!-- Коментар -->
  <p>це приклад</p>
  <span>з порожніми</span>
  
  <span>текстовими вузлами</span>
</div>

Спочатку ми отримаємо елемент #content та виведемо його вміст у консолі:

const content = document.getElementById('content');
console.log(content.childNodes); // NodeList(9) [text, <p>…</p>, text, comment, text, <p>…</p>, text, <span>…</span>, text, <span>…</span>]

Як ви можете бачити, в цьому прикладі є кілька порожніх текстових вузлів, а також коментар. Тепер застосуємо normalize() до елемента #content:

content.normalize();
console.log(content.childNodes); // NodeList(5) [<p>…</p>, comment, <p>…</p>, <span>…</span>, <span>…</span>]

Після нормалізації порожні текстові вузли були видалені, а суміжні текстові вузли ("з порожніми" та "текстовими вузлами") були об'єднані в один текстовий вузол.

Метод normalize() також може бути корисним при роботі з фрагментами документа (DocumentFragment). Наприклад, припустимо, ми створюємо фрагмент документа та додаємо до нього вузли:

const fragment = new DocumentFragment();
fragment.appendChild(document.createTextNode('Привіт, '));
fragment.appendChild(document.createElement('span')).textContent = 'світе';
fragment.appendChild(document.createTextNode(''));
fragment.appendChild(document.createTextNode('!'));

console.log(fragment.childNodes); // NodeList(4) [text, <span>…</span>, text, text]

Перед додаванням фрагмента до DOM ми можемо нормалізувати його, щоб видалити порожні текстові вузли:

fragment.normalize();
console.log(fragment.childNodes); // NodeList(2) [text, <span>…</span>]

Тепер фрагмент документа має лише два вузли: текстовий вузол "Привіт, " та елемент <span>.

Нормалізація дерева документа може бути корисною в різних ситуаціях, таких як оптимізація продуктивності, полегшення маніпуляцій з DOM та забезпечення коректної роботи деяких методів і властивостей DOM. Наприклад, метод Node.textContent може повертати неочікувані результати, якщо в дереві документа є порожні текстові вузли.

Крім того, нормалізація може бути особливо важливою при роботі з фреймворками та бібліотеками, які активно маніпулюють DOM, такими як React, Vue або Angular. Ці фреймворки часто створюють тимчасові фрагменти документа та додають їх до DOM після певних обчислень або операцій. Нормалізація цих фрагментів перед додаванням до DOM може покращити продуктивність та уникнути непередбачуваної поведінки.

Однак, слід зазначити, що нормалізація дерева документа може бути дорогою операцією, особливо для великих DOM-дерев. Тому її слід використовувати з обережністю та лише в тих випадках, коли вона дійсно необхідна. Зазвичай, сучасні браузери достатньо ефективно працюють з DOM-деревами, навіть якщо вони містять порожні текстові вузли.

Також важливо пам'ятати, що document.normalize() нормалізує лише поточний вузол та його нащадків. Якщо потрібно нормалізувати все дерево документа, необхідно викликати цей метод на об'єкті document.

Ще один важливий нюанс полягає в тому, що document.normalize() не видаляє коментарі з дерева документа. Якщо необхідно видалити коментарі, слід використовувати інші методи, такі як Node.removeChild() або DocumentFragment.

Загалом, document.normalize() є корисним інструментом для оптимізації та спрощення структури DOM, але його слід використовувати обережно та лише в тих випадках, коли це дійсно необхідно для покращення продуктивності або коректної роботи додатку.

автор: Bond

Порада

Якщо ви працюєте з DocumentFragment, обов'язково нормалізуйте його перед додаванням до DOM-дерева. Фрагменти документа часто створюються динамічно, і в них можуть потрапляти порожні текстові вузли або роздроблені текстові вузли. Перед додаванням фрагмента до DOM викличте fragment.normalize(), щоб очистити його структуру.

автор: Bond
Порада

Якщо ви працюєте з великими DOM-деревами, будьте обережні з використанням normalize(), оскільки ця операція може бути ресурсномісткою. Замість того, щоб нормалізувати все дерево документа за допомогою document.normalize(), розгляньте можливість нормалізації лише певних вузлів або фрагментів, які потребують оптимізації.

автор: Bond

Синтаксис

normalize()

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
1 1 1 ≤12.1 12 9
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
4.4 18 4 1

Приклади

+ запропонувати свій приклад у пісочниці

У цьому прикладі ми створюємо елемент div з id="myElement" та додаємо до нього дочірні вузли, включаючи порожні текстові вузли. Спочатку ми виводимо кількість дочірніх вузлів, яка буде більшою, ніж очікувалося, через наявність порожніх текстових вузлів. Потім ми викликаємо метод normalize() на елементі, що видалить порожні текстові вузли та об'єднає суміжні текстові вузли. Нарешті, ми виводимо оновлену кількість дочірніх вузлів, яка буде меншою, ніж до нормалізації.

HTML

<div id="myElement">Демонстраційний елемент</div>

JS

// Отримуємо елемент, з яким будемо працювати
const element = document.getElementById('myElement');

// Додаємо дочірні елементи з порожніми текстовими вузлами
element.innerHTML = 'Текст 1 <span>Span 1</span> Текст 2';

// Виводимо поточну кількість дочірніх вузлів
console.log(`Кількість дочірніх вузлів до нормалізації: ${element.childNodes.length}`);

// Нормалізуємо вузол
element.normalize();

// Виводимо оновлену кількість дочірніх вузлів
console.log(`Кількість дочірніх вузлів після нормалізації: ${element.childNodes.length}`);
автор: Bond

У цьому прикладі ми створюємо функцію createFragmentWithEmptyTextNodes, яка повертає DocumentFragment з порожніми текстовими вузлами та елементом span. Ми отримуємо елемент div з id="myElement" та створюємо фрагмент документа за допомогою функції.

Потім ми викликаємо метод normalize() на фрагменті документа, що видалить порожні текстові вузли та об'єднає суміжні текстові вузли. Після нормалізації ми виводимо оновлену кількість дочірніх вузлів у фрагменті, яка буде меншою, ніж до нормалізації.

Нарешті, ми додаємо нормалізований фрагмент документа до елемента div з id="myElement" за допомогою методу appendChild. Таким чином, ми забезпечуємо, що структура DOM залишається чистою та оптимізованою, уникаючи непотрібних порожніх текстових вузлів.

HTML

<div id="myElement">Демонстраційний елемент</div>

JS

// Функція для створення фрагмента документа з порожніми текстовими вузлами
function createFragmentWithEmptyTextNodes() {
  const fragment = document.createDocumentFragment();
  fragment.appendChild(document.createTextNode('Текст 1'));
  fragment.appendChild(document.createElement('span')).textContent = 'Span 1';
  fragment.appendChild(document.createTextNode(''));
  fragment.appendChild(document.createTextNode('Текст 2'));
  fragment.appendChild(document.createTextNode(''));
  return fragment;
}

// Отримуємо елемент, до якого будемо додавати фрагмент
const element = document.getElementById('myElement');

// Створюємо фрагмент з порожніми текстовими вузлами
const fragment = createFragmentWithEmptyTextNodes();

// Виводимо поточну кількість дочірніх вузлів у фрагменті
console.log(`Кількість дочірніх вузлів у фрагменті до нормалізації: ${fragment.childNodes.length}`);

// Нормалізуємо фрагмент
fragment.normalize();

// Виводимо оновлену кількість дочірніх вузлів у фрагменті
console.log(`Кількість дочірніх вузлів у фрагменті після нормалізації: ${fragment.childNodes.length}`);

// Додаємо нормалізований фрагмент до елемента
element.appendChild(fragment);
автор: Bond

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле саме підкаже шляхи, а хибний підкреслить хвилею.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле саме підкаже шляхи, а хибний підкреслить хвилею.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле саме підкаже шляхи, а хибний підкреслить хвилею.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле саме підкаже шляхи, а хибний підкреслить хвилею.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід