Чтобы устроиться на работу фронтенд-разработчиком, нам нужно пройти собеседование по кодированию.
В этой статье мы рассмотрим несколько более сложных вопросов о манипуляциях с DOM.
Как проверить, является ли элемент потомком родительского элемента?
Мы можем использовать свойство parentNode
элемента DOM, чтобы проверить, является ли элемент дочерним по отношению к другому элементу.
Например, мы пишем следующую функцию проверки, является ли узел родительским для дочернего узла:
const isDescendant = (parent, child) => { while (child.parentNode) { if (child.parentNode == parent) return true; else child = child.parentNode; } return false; }
В функции isDescendant
мы получаем родительский узел child
со свойством parentNode
, пока не достигнем верхнего уровня.
В каждом родительском элементе мы проверяем, ссылается ли свойство parentNode
на тот же узел, что и parent
.
Мы возвращаем true
, если это так. В противном случае, мы переходим к вершине прародителя, прадедушки и прадедушки до самого верхнего уровня и возвращаем true
, если обнаруживаем, что parentNode
является тем же узлом, что и parent
.
В противном случае мы возвращаем false
, если ни один из них не совпадает с parent
.
Например, если у нас есть следующий HTML:
<div> <p> <span></span> </p> </div> <div id='foo'></div>
Тогда, если у нас есть следующий код:
const div = document.querySelector('div'); const p = document.querySelector('p'); const span = document.querySelector('span'); const foo = document.querySelector('#foo'); console.log(isDescendant(div, p)); console.log(isDescendant(div, span)); console.log(isDescendant(foo, span));
Первые 2 должны регистрировать true
, а последний - false
, поскольку первый div является родителем p и прародителем диапазона.
Div с идентификатором foo не является родительским ни для одного из других узлов.
В чем разница между innerHTML и appendChild?
innerHTML
удаляет все текущие дочерние узлы элементов. Затем интерпретатор JavaScript анализирует строку и затем назначает проанализированную строку элементу в качестве дочерних элементов.
appendChild
присоединяет дочерний узел к родительскому узлу, который он вызвал, как следует из названия.
Например, если у нас есть следующий HTML:
<div> <p>foo</p> </div>
Тогда если мы напишем:
const div = document.querySelector('div'); div.innerHTML = '<p>bar</p>';
Тогда мы видим на экране только «полосу», поскольку мы устанавливаем свойство innerHTML
для перезаписи того, что там есть.
С другой стороны, если мы используем appendChild
следующим образом:
const div = document.querySelector('div'); const p = document.createElement("p"); const bar = document.createTextNode("bar"); p.appendChild(bar); div.appendChild(p);
Затем мы добавляем элемент p с текстовым узлом «bar» и вызовом appendChild
для добавления p
к div
, мы видим:
foo bar
отображается на экране, так как мы добавили нового дочернего элемента в конец списка дочерних элементов в div.
Что такое createDocumentFragment и почему вы можете его использовать?
document.createDocumentFragment
позволяет нам создать новый DocumentFragment
, в который можно добавлять узлы DOM для построения закадрового дерева DOM.
Например, если у нас есть следующий HTML:
<ul></ul>
Затем мы можем использовать createDocumentFragment
следующим образом, чтобы создать закадровый фрагмент, а затем вставить все это в DOM:
const element = document.querySelector('ul'); const fragment = document.createDocumentFragment(); const fruits = ['apple', 'orange', 'grape']; fruits.forEach((fruit) => { const li = document.createElement('li'); li.textContent = fruit; fragment.appendChild(li); }); element.appendChild(fragment);
С помощью createDocumentFragment
мы сначала добавили все узлы во фрагмент, а затем добавили все это в наш элемент ul
с помощью appendChild
.
DocumentFragment
- это легкая или минимальная часть DOM или поддерева DOM. Это полезно для многократного манипулирования частью DOM.
DocumentFragments
управляются в памяти, поэтому для ЦП не требуются дорогостоящие операции.
Что такое оплавление? Что вызывает оплавление? Как мы могли уменьшить оплавление?
Reflow - это ситуация, когда мы меняем положение элементов в соответствии с размером экрана или изменением положения.
Если мы изменим ширину экрана, например, когда мы поворачиваем экран телефона, тогда все должно быть перемещено для отображения в свойстве screen.
Перекомпоновка обходится дорого, поскольку все приходится перемещать, особенно на небольших устройствах, таких как телефоны.
Перекомпоновка вызывается изменением макета, изменением размера окна, изменением размера любого элемента, изменением шрифтов любым способом, перемещением элементов DOM, добавлением или удалением таблиц стилей и всем остальным, что вносит аналогичные виды изменений.
Чтобы избежать перекомпоновки, мы избегаем установки нескольких встроенных стилей, применяем анимацию к элементам с фиксированным или абсолютным положением и избегаем использования таблиц для макета.
Заключение
Мы можем использовать свойство parentNode
узла, чтобы получить родителя узла.
Установка свойства innerHTML
элемента перезаписывает все существующие дочерние элементы и заменяет их новыми из заданной нами строки.
appendChild
присоединяет новый дочерний элемент к концу поддерева.
DocumentFragments
- это легкие закадровые элементы, которые содержат элементы DOM. Он управляется в памяти и может быть добавлен на экран, как и любой другой элемент.
Reflow - это изменение положения элементов в соответствии с некоторыми другими изменениями на экране. Это дорогостоящая операция, которой следует избегать.