相同的标题会导致相同的ID和锚点

您好,

我发现了一个 bug(或者技术限制)。如果标题名称相同,目录(TOC)中的链接以及滚动时的突出显示将无法正常工作。我猜是因为没有生成唯一的 ID,而是 ID 仅为标题的名称。

在我的例子中,目录(TOC)看起来像这样——来自教育背景,我们的学习单元结构始终相同,例如:

  • 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本身固有的问题,并非bug,所以这是一个技术限制。

一段使用你所描述的主题组件来展示此行为的视频:

我认为它的优先级很低,但如果有人想尝试,我很欢迎进行更改,所以我将为此添加一个#pr-welcome标签。 :slight_smile:

1 个赞

嗯,不是的,锚点正在获得唯一的 name 属性

# Heading level A
foo

## Heading level B
bar

## Heading level B
bar

# Heading level A
foo

## Heading level B
bar

## Heading level B
bar

生成:(请注意 -1 -2 -3 等)


<h1 dir="ltr">
  <a name="heading-level-a-1" class="anchor" href="#heading-level-a-1"></a>Heading level A
</h1>
<p dir="ltr">foo</p>
<h2 dir="ltr">
  <a name="heading-level-b-2" class="anchor" href="#heading-level-b-2"></a>Heading level B
</h2>
<p dir="ltr">bar</p>
<h2 dir="ltr">
  <a name="heading-level-b-3" class="anchor" href="#heading-level-b-3"></a>Heading level B
</h2>
<p dir="ltr">bar</p>
<h1 dir="ltr">
  <a name="heading-level-a-4" class="anchor" href="#heading-level-a-4"></a>Heading level A
</h1>
<p dir="ltr">foo</p>
<h2 dir="ltr">
  <a name="heading-level-b-5" class="anchor" href="#heading-level-b-5"></a>Heading level B
</h2>
<p dir="ltr">bar</p>
<h2 dir="ltr">
  <a name="heading-level-b-6" class="anchor" href="#heading-level-b-6"></a>Heading level B
</h2>
<p dir="ltr">bar</p>

属性的值基于标题的内容,因此相同的标题将具有相同的 iddata-d-toc 属性:

最后一个“Aim”标题:

导致第一个 Aim 具有 iddata-d-toc 属性,其值与最后一个 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 个赞