Найти в Дзене
Журнал «Код»

Автоматическое оглавление на странице

Поручите это машине.
Допустим, вы написали большую статью. В ней много разделов и заголовков — так нужно по смыслу.
Чтобы читатель как-то ориентировался в вашей статье, вы решаете сделать оглавление: из него можно перейти к любому разделу в статье, как в Википедии.
Вы собираете оглавление вручную, публикуете, а потом решаете поменять местами пару разделов или добавить новые. Оглавление тоже
Оглавление

Поручите это машине.

Допустим, вы написали большую статью. В ней много разделов и заголовков — так нужно по смыслу.

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

Вы собираете оглавление вручную, публикуете, а потом решаете поменять местами пару разделов или добавить новые. Оглавление тоже придётся переделать. Ну уж нет!

Сегодня напишем скрипт, который сам соберёт оглавление для ваших эпических лонгридов.

Задача скрипта

  1. Найти все подзаголовки <h2> на странице
  2. Собрать их в одном месте
  3. Сделать из них ссылки

Подготовка

Возьмём стандартный шаблон страницы и заполним его текстом из нашей статьи про чужой код:

Пока нам нужен просто текст с заголовками.
Пока нам нужен просто текст с заголовками.

Добавляем место для оглавления

Мы будем делать оглавление в виде маркированного списка с буллетами, но вы можете сделать его каким угодно. Главное — понимать принцип работы.

Для такого списка нам понадобится тег <ul>..</ul>, внутри которого и будет наше оглавление. На старте мы не знаем, что в него положит скрипт, поэтому сделаем его пустым и добавим в самое начало страницы:

<ul id="nav"></ul>

Чтобы из скрипта мы смогли обратиться к этому элементу и работать с ним напрямую, сразу дадим ему название — nav. Можно дать любое другое и просто указать это в скрипте.

Пишем скрипт

Первым делом подключаем jQuery — он нам поможет работать с элементами на странице:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Сам скрипт должен делать вот что:

  1. Найти все подзаголовки <h2>.
  2. Добавить к ним id с каким-то именем, чтобы можно было переходить к нему из оглавления.
  3. Добавить новый элемент в оглавление с таким же названием, как и подзаголовок.
  4. Сделать из него внутреннюю ссылку, чтобы можно было перейти в нужную часть статьи.

Немного о внутренних ссылках

Обычно ссылки ведут на другие страницы. Когда страница загружается, мы видим её верхнюю часть и скроллим вниз. Интуитивно понятно.

Но есть и такая штука: с помощью специальной метки можно заставить браузер показать нам не верх страницы, а какое-то её конкретное место. Такая метка называется якорем.

Чтобы якорь сработал, нужно две вещи:

  1. Дать специальное имя какому-то объекту на странице. Для этого используют свойство тега id="name", где name — любое название.
  2. В адресе страницы в конце добавить маркер #name — что означает «доскролль до объекта с id="name"».

Получается, что, если браузер видит в адресе #name, он находит нужный объект на странице и сразу мгновенно доскролливает до него.

Например, нам нужно, чтобы страница сразу открылась на форме оплаты. Пишем в адресе page.html#payment, а в самой странице говорим форме оплаты: id="payment" — и всё, она проскроллится до нужного места. И потом можно скроллить, как нам нужно. Ссылка должна выглядеть так:

<a href="page.html#payment">Оплатить</a>

А если нужно перекинуть на нужное место в странице, то просто:

<a href="#payment">Оплатить</a>

Боевой скрипт

Теперь посмотрим на скрипт, который делает именно то, что нам нужно. Читайте комментарии в коде, чтобы понять, что происходит:

Вся магия здесь в двух моментах:

  1. Три точки в команде ...document.querySelectorAll('h2') позволяют нам найти все элементы на странице, обозначенные тэгом h2 — так мы находим все подзаголовки.
  2. Эта команда взяла порядковый номер этого подзаголовка (нулевой, так как считается с нуля), добавила его в ссылку, потом взяла текст самого заголовка, добавила его в текст ссылки и из всего этого сделала кусок HTML-кода. Теперь, когда последняя команда добавит его на страницу, браузер сможет его прочитать и обработать как нужно.Команда links.push(`<li><a href="#h2-${i}">${el.textContent}</a></li>`); формирует новую строчку оглавления, которая для первого подзаголовка будет выглядеть, например, вот так: <li><a href="#h2-1">Ситуация</a></li>

Добавим наш скрипт в самый конец страницы. Теперь, если мы что-то поменяем в структуре страницы, добавим или уберём какие-то подзаголовки, оглавление само найдёт все изменения и сделает правильные ссылки.

👉 Если его поставить в начало, то он не будет работать — на момент запуска скрипта на странице не успеет появиться ни одного подзаголовка.

Автоматическое оглавление точно повторяет все названия наших подзаголовков.
Автоматическое оглавление точно повторяет все названия наших подзаголовков.

Что дальше

У нас простое, но не самое универсальное решение — скрипт не обращает внимания на более мелкие подзаголовки — <h3>, <h4> и так далее. Но, владея знаниями из этой статьи, вы сможете без проблем это исправить.