Node.normalize(): восстановление нормализованной формы текстовых узлов в DOM!После операций с
Text,
Range и точечной модификации DOM содержимое элемента может оказаться фрагментировано на несколько соседних текстовых узлов.
const container = document.createElement('div');
const text = document.createTextNode('Hello');
container.append(text);
const tail = text.splitText(2);
console.log([...container.childNodes].map(node => node.data));
// ['He', 'llo']Для рендеринга это обычно не имеет значения:
console.log(container.textContent);
// Hello
Но для кода, который анализирует структуру дерева через
childNodes,
firstChild,
nextSibling или хранит ссылки на конкретные
Text-узлы, такая фрагментация уже существенна.
Метод
Node.normalize() приводит всё поддерево узла к нормализованной форме:
container.normalize();
console.log(container.childNodes.length);
// 1
console.log(container.firstChild.data);
// Hello
Нормализация выполняется рекурсивно и гарантирует, что в обработанном поддереве: не останется пустых текстовых узлов; не останется соседних текстовых узлов без разделяющего их элемента, комментария или другого типа узла.
При объединении данные последующих
Text-узлов добавляются к первому узлу группы, а сами последующие узлы удаляются из дерева.
console.log(tail.parentNode);
// null
Сохранённая ссылка
tail при этом не становится невалидной: объект продолжает существовать, но больше не является частью DOM-дерева.
Важно и другое:
normalize() не объединяет весь текст элемента в один узел, если между текстовыми узлами находятся другие узлы.
<p>Hello <strong>DOM</strong>!</p>
Здесь текст до и после
<strong> останется в разных
Text-узлах и после нормализации.
Метод особенно полезен после
splitText(), операций с
Range и редакторских сценариев, где текстовые узлы регулярно разрезаются и склеиваются:
const paragraph = document.createElement('p');
const text = document.createTextNode('Hello world');
paragraph.replaceChildren(text);
text.splitText(5);
console.log(paragraph.childNodes.length);
// 2
paragraph.normalize();
console.log(paragraph.childNodes.length);
// 1🔥
Node.normalize() не меняет текстовое содержимое элемента, но приводит его поддерево к нормализованной форме: без пустых и соседних текстовых узлов. Это полезно перед обходом DOM, сериализацией, сравнением структуры или выполнением алгоритмов, которые рассчитывают на предсказуемую организацию
Text-узлов.