В этой статье я собираюсь показать, как создать функцию getElementById, которая будет похожа на document.getElementById.

Итак, прежде чем мы начнем, я хочу уточнить, что document.getElementById делает. Это функция, которая при вызове с заданным идентификатором находит элемент DOM с тем же идентификатором, что и переданный функции. Если есть несколько идентификаторов, он вернет первый элемент. Прежде чем мы начнем писать нашу функцию, давайте быстро вспомним, как устроена модель DOM и какие полезные методы мы можем использовать.

ДОМ

С точки зрения непрофессионала DOM означает объектную модель документа, это древовидное представление элемента HTML. так, например, скажем, у нас есть следующий HTML:

<!DOCTYPE HTML>  
  <html>
    <head>       
      <title>Hello World</title>    
    </head>    
    <body>       
      <h1> A quick brown fox jumps over the lazy dog </h1>
      <div>
        <h2>This is a h2</h2>
        <p>This is a paragraph</p>
        <article>This is a article</article>       
      </div>    
    </body> 
 </html>

Для этого HTML DOM будет таким:

На изображении выше мы видим все узлы DOM для HTML. Существуют различные типы узлов DOM. Список можно посмотреть на MDN. document.getElementId работает с элементом HTML, а элементы HTML имеют nodeType из 1.

Итак, прежде всего нам нужно получить всех дочерних элементов document.body, мы можем сделать это, вызвав document.body.children, этот метод возвращает HTMLCollection, поэтому нам нужно преобразовать его в массив, теперь есть разные способы, с помощью которых мы можем это сделать, но самый простой - это просто использовал оператор расширения, например, [...root.children]. Теперь этот массив содержит всех дочерних элементов document.body.

Теперь мы будем перебирать массив, и во время каждой итерации мы будем выбирать элемент из массива и проверять, равен ли идентификатор элементов искомому идентификатору, это можно сделать, вызвав .id для выбранного элемента. если id совпадает, мы вернем элемент, в противном случае мы повторим тот же процесс для всех дочерних элементов текущего элемента. В информатике этот тип алгоритма называется поиском в глубину.

const walkDOM = (root, elementId) => {
    let result = null;
    const elements = [...root.children];
    for (let element of elements) {
        if (element.id === elementId) return element;
        if (element.children.length && element.nodeType === 1) {
            result = walkDOM(element, elementId);
            if (result) return result;
        }
    }
    return result;
};
const getElementById = (elementId) => {
    return walkDOM(document.body, elementId);
}

Обратите внимание, что это не замена document.getElementById, а простой фрагмент, показывающий, насколько мощным и многофункциональным является API DOM и как далеко мы можем зайти в веб-разработке, не зная, как работают эти методы.

Первоначально опубликовано на https://dev.to 27 февраля 2018 г.