Допустим, вы написали большую статью. В ней много разделов и заголовков — так нужно по смыслу.
Чтобы читатель как-то ориентировался в вашей статье, вы решаете сделать оглавление: из него можно перейти к любому разделу в статье, как в Википедии.
Вы собираете оглавление вручную, публикуете, а потом решаете поменять местами пару разделов или добавить новые. Оглавление тоже придётся переделать. Ну уж нет!
Сегодня напишем скрипт, который сам соберёт оглавление для ваших эпических лонгридов.
Задача скрипта
- Найти все подзаголовки <h2> на странице
- Собрать их в одном месте
- Сделать из них ссылки
Подготовка
Возьмём стандартный шаблон страницы и заполним его текстом из нашей статьи про чужой код:
<!DOCTYPE html>
<html>
<head>
<title>Автооглавление</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
</style>
<!-- Закрываем служебную часть страницы -->
</head>
<body>
<h2>Ситуация </h2>
<p>
Вам нужно решить задачу, с которой вы ещё не сталкивались, например, вывести данные в виде красивого графика.</p>
<p>
Можно с нуля погрузиться в графическую систему языка и за 3–4 дня разобраться, как это сделать. Это полезно, если
дальше вам нужно будет постоянно, каждый день рисовать новые графики. Вы освоите все возможности графической системы
и в дальнейшем будете рисовать графики легко и быстро.</p>
<p>
Но если эта функция вам нужна только один раз и больше вы не планируете ничего рисовать, то это очень нерациональный
ход — вы потратите много времени на то, что больше не пригодится.</p>
<h2>Решение</h2>
За 10 минут найти в интернете уже готовый код, который делает что нужно, адаптировать под свой проект и спокойно
продолжить работу. Код может быть неидеальным, не очень красиво написан, но:</p>
<p>
✔️ вы потратили в разы меньше времени;<br>
✔️ проект движется дальше, а не стоит на месте;<br>
✔️ вы примерно поняли, как это сделано, и если что — сможете повторить в другом проекте.</p>
<h2>Как сделать этот подход ещё лучше</h2>
<p>
Выучить английский. Большинство справочников разработчика и форумов с готовыми решениями — на английском. Чтобы
понять, что там написано, что делает код и для каких ситуаций он подходит, нужно знать английский хотя бы на базовом
уровне (а лучше — владеть техническим английским).</p>
<h2>Что может пойти не так</h2>
<p>
Бывает, что разработчик без разбора копипастит код с форумов. Он не разбирается в том, что за код он использует, а
просто вставляет его в свой проект. Работает — и ладно.</p>
<p>
А может оказаться, что, например, код плохо оптимизирован и будет со страшной силой тормозить всю программу; или в
коде могут быть ошибки, которые проявятся при дальнейшей эксплуатации; или на тестовых данных всё работало, а в
реальности ломается.</p>
</body>
<!-- Конец всей страницы -->
</html>
Добавляем место для оглавления
Мы будем делать оглавление в виде маркированного списка с буллетами, но вы можете сделать его каким угодно. Главное — понимать принцип работы.
Для такого списка нам понадобится тег <ul>..</ul>
, внутри которого и будет наше оглавление. На старте мы не знаем, что в него положит скрипт, поэтому сделаем его пустым и добавим в самое начало страницы:
<ul id="nav"></ul>
Чтобы из скрипта мы смогли обратиться к этому элементу и работать с ним напрямую, сразу дадим ему название — nav. Можно дать любое другое и просто указать это в скрипте.
Пишем скрипт
Скрипт должен делать вот что:
- Найти все подзаголовки <h2>.
- Добавить к ним id с каким-то именем, чтобы можно было переходить к нему из оглавления.
- Добавить новый элемент в оглавление с таким же названием, как и подзаголовок.
- Сделать из него внутреннюю ссылку, чтобы можно было перейти в нужную часть статьи.
Немного о внутренних ссылках
Обычно ссылки ведут на другие страницы. Когда страница загружается, мы видим её верхнюю часть и скроллим вниз. Интуитивно понятно.
Но есть и такая штука: с помощью специальной метки можно заставить браузер показать нам не верх страницы, а какое-то её конкретное место. Такая метка называется якорем.
Чтобы якорь сработал, нужно две вещи:
- Дать специальное имя какому-то объекту на странице. Для этого используют свойство тега id="name", где name — любое название.
- В адресе страницы в конце добавить маркер #name — что означает «доскролль до объекта с id="name"».
Получается, что, если браузер видит в адресе #name, он находит нужный объект на странице и сразу мгновенно доскролливает до него.
Например, нам нужно, чтобы страница сразу открылась на форме оплаты. Пишем в адресе page.html#payment, а в самой странице говорим форме оплаты: id="payment" — и всё, она проскроллится до нужного места. И потом можно скроллить, как нам нужно. Ссылка должна выглядеть так:
<a href="page.html#payment">Оплатить</a>
А если нужно перекинуть на нужное место в странице, то просто:
<a href="#payment">Оплатить</a>
Боевой скрипт
Теперь посмотрим на скрипт, который делает именно то, что нам нужно. Читайте комментарии в коде, чтобы понять, что происходит:
// создаём пока пустой массив, где будут жить наше оглавление
const links = [];
// находим все подзаголовки и добавляем им id, который состоит из слова h2- и порядкового номера этого заголовка
[...document.querySelectorAll('h2')].forEach((el, i) => {
// присваиваем id каждому элементу, добавляя к нему порядковый номер этого элемента
el.id = `h2-${i}`;
// отправляем в наш изначально пустой массив новый элемент с уже готовым HTML-кодом для ссылки
links.push(`<li><a href="#h2-${i}">${el.textContent}</a></li>`);
});
// отправляем наш код в раздел nav, который отвечает за оглавление
nav.innerHTML = links.join('');
Вся магия здесь в двух моментах:
- Три точки в команде
...document.querySelectorAll('h2')
позволяют нам найти все элементы на странице, обозначенные тэгом h2 — так мы находим все подзаголовки. - Команда
links.push(`<li><a href="#h2-${i}">${el.textContent}</a></li>`);
формирует новую строчку оглавления, которая для первого подзаголовка будет выглядеть, например, вот так:
<li><a href="#h2-1">Ситуация</a></li>
Эта команда взяла порядковый номер этого подзаголовка (нулевой, так как считается с нуля), добавила его в ссылку, потом взяла текст самого заголовка, добавила его в текст ссылки и из всего этого сделала кусок HTML-кода. Теперь, когда последняя команда добавит его на страницу, браузер сможет его прочитать и обработать как нужно.
Добавим наш скрипт в самый конец страницы. Теперь, если мы что-то поменяем в структуре страницы, добавим или уберём какие-то подзаголовки, оглавление само найдёт все изменения и сделает правильные ссылки.
👉 Если его поставить в начало, то он не будет работать — на момент запуска скрипта на странице не успеет появиться ни одного подзаголовка.
Что дальше
У нас простое, но не самое универсальное решение — скрипт не обращает внимания на более мелкие подзаголовки — <h3>, <h4> и так далее. Но, владея знаниями из этой статьи, вы сможете без проблем это исправить.