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

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

easy

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

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

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

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

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

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

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

Подготовка

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

<!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. Можно дать любое другое и просто указать это в скрипте.

Пишем скрипт

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

  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>

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

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

// создаём пока пустой массив, где будут жить наше оглавление
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('');

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

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

<li><a href="#h2-1">Ситуация</a></li>

Эта команда взяла порядковый номер этого подзаголовка (нулевой, так как считается с нуля), добавила его в ссылку, потом взяла текст самого заголовка, добавила его в текст ссылки и из всего этого сделала кусок HTML-кода. Теперь, когда последняя команда добавит его на страницу, браузер сможет его прочитать и обработать как нужно.

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

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

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

Что дальше

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

Обложка:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Маша Климентьева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Вам может быть интересно
easy