Чтобы устроиться на работу фронтенд-разработчиком, нам нужно пройти собеседование по кодированию.

В этой статье мы рассмотрим несколько более сложных вопросов о манипуляциях с 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 - это изменение положения элементов в соответствии с некоторыми другими изменениями на экране. Это дорогостоящая операция, которой следует избегать.