Идентичные заголовки приводят к одинаковым id и якорям

Привет,

Я обнаружил ошибку (?) или техническое ограничение. Ссылки в оглавлении, а также подсветка при прокрутке работают некорректно, если заголовки имеют одинаковые названия. Думаю, это связано с тем, что генерируется не уникальный ID, а ID совпадает с названием заголовка.

В моём случае оглавление выглядит так — благодаря педагогическому образованию структура наших учебных модулей всегда одинакова, например:

  • H1 - Обзор
  • H1 - 0:00 > 0:15 - Пленарное заседание и введение
    • H2 - Цель
    • H2 - Содержание
    • H2 - Методика
    • H2 - Советы
    • H2 - Слайды
  • H1 - 0:15 > 0:45 - Работа в группах
    • H2 - Цель
    • H2 - Содержание
    • H2 - Методика
    • H2 - Советы
    • H2 - Слайды
  • H1 - 0:45 > 0:60 - Индивидуальная работа
    • H2 - Цель
    • H2 - Содержание
    • H2 - Методика
    • H2 - Советы
    • H2 - Слайды
  • H1 - 0:60 > 0:90 - Пленарное обсуждение
    • H2 - Цель
    • H2 - Содержание
    • H2 - Методика
    • H2 - Советы
    • H2 - Слайды

Думаю, можно было бы сделать заголовки H2 более информативными, но это противоречит идее единой структуры для всех учебных модулей. Особенно в случаях «Советы» и «Слайды» добавить больше информации сложно.

Возможно, вся эта проблема связана с упомянутым выше вопросом, но я не настолько эксперт.

6 лайков

Это не ошибка, а особенность самого HTML, поэтому это техническое ограничение.

Видео, демонстрирующее такое поведение с использованием компонента темы, как вы описали:

Я считаю, что это задача с низким приоритетом, но изменения были бы кстати, поэтому я добавлю тег pr-welcome, если кто-то захочет этим заняться. :slight_smile:

1 лайк

Хм, нет, у якорей генерируются уникальные атрибуты name

# Заголовок уровня A
foo

## Заголовок уровня B
bar

## Заголовок уровня B
bar

# Заголовок уровня A
foo

## Заголовок уровня B
bar

## Заголовок уровня B
bar

генерирует: (обратите внимание на -1 -2 -3 и т.д.)

<h1 dir="ltr">
  <a name="heading-level-a-1" class="anchor" href="#heading-level-a-1"></a>Заголовок уровня A
</h1>
<p dir="ltr">foo</p>
<h2 dir="ltr">
  <a name="heading-level-b-2" class="anchor" href="#heading-level-b-2"></a>Заголовок уровня B
</h2>
<p dir="ltr">bar</p>
<h2 dir="ltr">
  <a name="heading-level-b-3" class="anchor" href="#heading-level-b-3"></a>Заголовок уровня B
</h2>
<p dir="ltr">bar</p>
<h1 dir="ltr">
  <a name="heading-level-a-4" class="anchor" href="#heading-level-a-4"></a>Заголовок уровня A
</h1>
<p dir="ltr">foo</p>
<h2 dir="ltr">
  <a name="heading-level-b-5" class="anchor" href="#heading-level-b-5"></a>Заголовок уровня B
</h2>
<p dir="ltr">bar</p>
<h2 dir="ltr">
  <a name="heading-level-b-6" class="anchor" href="#heading-level-b-6"></a>Заголовок уровня B
</h2>
<p dir="ltr">bar</p>

Значения атрибутов основаны на содержании заголовков, поэтому одинаковые заголовки будут иметь идентичные атрибуты id и data-d-toc:

Последний заголовок «Aim»:

Приводит к первому элементу «Aim», у которого атрибуты id и data-d-toc имеют то же значение, что и последний элемент оглавления:

1 лайк

Верно, поэтому это не является внутренним ограничением HTML (на самом деле наличие идентичных id в одном документе нарушает спецификацию), а представляет собой ошибку в компоненте темы.

Полагаю, что этот код

const suffix = slugify(h.textContent) || index;
const id = h.getAttribute("id") || slugify(`toc-${h.nodeName}-${suffix}`);

должен быть изменён на что-то вроде

const suffix = slugify(h.textContent) || '';
const id = h.getAttribute("id") || slugify(`toc-${h.nodeName}-${suffix}-${index}`);
6 лайков