Для работы с JavaScript в браузере важно понимать то, как браузеры работают хотя бы в общих чертах. Возьмём любую страницу и рассмотрим основные шаги, которые выполняет браузер для её отображения.
С высоты птичьего полета процесс отображения страницы можно представить следующим образом:
Браузер выполняет запрос на сервер (предварительно выяснив этот адрес с помощью DNS)
GET /courses HTTP/1.1
HOST: ru.hexlet.io
В ответ сервер отправляет HTML.
Когда HTML получен, браузер начинает его разбор (говорят парсинг) и формирование внутренней структуры под названием DOM-дерево.
Затем это дерево (а не исходный HTML) используется для физической отрисовки страницы, которую мы и наблюдаем.
Что такое DOM-дерево и зачем оно нужно для формирования страницы, когда у нас есть HTML? Дело в том, что HTML это просто текст. Его крайне неудобно использовать напрямую (скорее даже невозможно в данном случае). Гораздо проще создать на его базе объект, который будет соответствовать структуре самого HTML. Затем использовать его для формирования страницы. Именно этим объектом и является DOM-дерево.
Слово дерево здесь используется не просто так. HTML имеет древовидную структуру. Теги вкладываются в другие теги, которые вкладываются в другие теги и так до бесконечности. Поэтому и получившийся объект имеет такую же, древовидную структуру.
Примерно то же самое происходит с исходным текстом программы на JavaScript. Для интерпретатора текст неудобен и поэтому код внутри JavaScript сначала превращается в AST (Абстрактное Синтаксическое Дерево), которое уже затем используется для запуска
Браузер формирует DOM-дерево где-то внутри себя, но вместе с этим, он предоставляет механизм для создания DOM-дерева прямо из JavaScript.
const html = `
<body>
<p>hello, <b>world</b>!</p>
</body>
`;
const parser = new DOMParser();
// Каждый html-тег становится узлом этого дерева,
// а теги, вложенные в него, становятся дочерними узлами.
// Для представления текста создаются специальные текстовые узлы.
// Важно то, что в DOM-дерево попадают все элементы,
// представленные в html, включая пробелы и переводы строк.
const doc = parser.parseFromString(html, 'text/html');
// Выводим содержимое тега <body>
console.log(doc.body.innerHTML);
Объект, полученный выше, имеет определенную структуру, которая будет одинаковой во всех браузерах и других программах, работающих с HTML. Именно поэтому он содержит приставку DOM. Объектная модель документа (Document Object Model) — это не зависящий от платформы и языка формат, позволяющий программам и скриптам получить доступ к содержимому HTML-документов, а также изменять их содержимое, структуру и оформление.
Благодаря наличию этого стандарта у нас есть возможность писать одну версию кода для всех браузеров. Иначе, если бы каждый браузер делал, что хотел, пришлось бы писать код под каждый браузер индивидуально из-за их несовместимости. Однако, различия всё равно присутствуют. Браузеры развиваются с разной скоростью и не всегда поспевают за изменениями в стандарте DOM. Поэтому программистам приходится ждать появления новых возможностей в большинстве браузеров перед тем как они смогут их использовать. В более поздних уроках мы поговорим о том, как современные разработчики справляются с этими проблемами, используя полифиллы.
DOM-дерево текущей страницы доступно в JavaScript в виде объекта document
, который наполнен большим количеством методов (согласно спецификации DOM) для манипулирования этим деревом. Любые изменения, которые производятся с ним, сразу же отображаются браузером на странице.
Например:
// Вся страница (тег body) заменится на этот заголовок
document.body.innerHTML = '<h1>For Hexlet!</h1>';
Те, кто сталкивались с HTML в реальной жизни, прекрасно знают, что если подать на вход браузеру ошибочный HTML с незакрытыми тегами, нарушенной вложенностью и другими проблемами, то мы не получим сообщений об ошибках. Браузер переварит этот HTML и что-то отобразит на экране. Возможно, вам не понравится увиденное, но оно будет работать.
// Этот HTML содержит ошибки, но браузер его отобразит
const html = '</p>hello, hexlet<div>';
Браузер действительно восстанавливает структуру документа и делает это по очень хитрым правилам. И это логично, иначе было бы невозможно произвести парсинг в принципе. Но есть и другая причина: даже если сам HTML будет правильным, браузер при создании DOM-дерева добавляет в него узлы, представленные тегами в html, которые вы, возможно, пропустили, но стандарт требует их наличия. Например, в таблицы добавляется <tbody>
и не важно был он в исходном HTML или нет.
Именно DOM открывает практически безграничные возможности по изменению страниц. Все библиотеки (jquery и другие) и фреймворки (angular, react) внутри себя манипулируют DOM. Это та база, вокруг которой построено всё во фронтенд-разработке.
Используйте объект document
для замены тела документа (как в примере выше) на следующий фрагмент:
<h1>This is my territory</h1>
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Статья «Ловушки обучения»
Вебинар «Как самостоятельно учиться»
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт