craftsnippets/table-of-contents

此插件可从文本中的HTML标题生成目录。

3.0.0 2024-04-02 08:37 UTC

This package is not auto-updated.

Last update: 2024-09-17 10:38:52 UTC


README

此插件可从文本中的HTML标题生成目录。目录中的锚点链接直接指向文本中的相应标题。

目录可以嵌套 - 嵌套级别将基于标题级别。

以下是插件生成的示例目录截图

Screenshot

要求

此插件需要Craft CMS 3.0.0-beta.23或更高版本。

它还需要Anchors插件,因为它使用了其内部功能。

安装

您可以从插件商店或使用Composer安装此插件。

要使用Composer安装插件,请运行以下命令

composer require craftsnippets/table-of-contents

然后,在控制面板中转到设置,插件 - 并单击“table of contents”旁边的“安装”。

用法

要创建目录,您需要将包含标题的HTML传递给craft.toc.getLinks函数,并使用{% nav %}Twig标签输出返回的数据。

别忘了也使用Anchors插件提供的anchors过滤器处理您的HTML - 它将为标题添加id属性,以便目录中的锚点链接有可指向的对象。

请记住在使用getLinks函数后将HTML传递给anchors过滤器。否则,目录中的链接将包含由Anchors插件添加到标题中的链接的转义HTML内容。

{% set text %}
some text with headers...
{% endset %}

{% set table = craft.toc.getLinks(text) %}

 <ul>
    {% nav link in table %}
        <li>
            <a href="{{ link.hash }}">{{ link.text }}</a>
            {% ifchildren %}
                <ul>
                    {% children %}
                </ul>
            {% endifchildren %}
        </li>
    {% endnav %}
</ul>

{{text|anchors}}

别忘了为每个链接留出一些左边距,以显示它们的层次结构。

li{
  margin-left: 1rem;
}

嵌套数字列表

要显示目录中链接前的数字计数,您可以使用一些CSS。这对于嵌套列表也适用。

ul {
  counter-reset: section;               
  list-style-type: none;
}
li::before {
  counter-increment: section;            
  content: counters(section, ".") " "; 
}

替代标题标签

默认情况下,目录插件搜索h1h2h3标签。就像在Anchors插件中一样,这可以通过传递getLinks函数的第二个参数来覆盖。

{% table = craft.toc.getLinks(text, 'header1,header2,header3') %}

使用anchors过滤器时,请务必执行相同的操作。

非ASCII字符映射

getLinks()方法的第三个参数可以用来更改用于生成链接散列的非ASCII字符,就像在Anchors插件中一样。以下是Anchors插件文档中的引用

锚点过滤器将任何非ASCII字符转换为ASCII,默认情况下使用当前站点的语言的ASCII字符映射。如果您正在显示与当前站点不同的语言的内容,请使用语言参数来覆盖应使用哪种ASCII字符映射。

以下是示例用法

{% set tableOfContents = craft.toc.getLinks(html, 'h1,h2,h3', entry.site.language) %}

从链接文本中删除标签

如果转换为链接的标题包含一些HTML标签,目录中的链接将包含这些标签。您可以通过将getLinks()方法的第四个参数设置为true来禁用此功能。

{% set tableOfContents = craft.toc.getLinks(html, 'h1,h2,h3', null, true) %}

平滑滚动

您可以通过单个CSS属性实现平滑滚动效果。

html{
   scroll-behavior: smooth;
}

不幸的是,它在Safari或IE上不起作用 - 更多信息请参见caniuse

以下是在所有现代浏览器中都能实现相同效果的jQuery代码

  $('.table-of-contents a').on('click', function(event) {
    var hash = '#' + $(this).attr('href').split('#')[1]
    var element = $(hash)
    if (element.length) {
      event.preventDefault();
      history.pushState(hash, undefined, hash)
      $('html, body').animate({scrollTop: element.offset().top}, 500)
    }
  });   

  window.addEventListener('popstate', function(e) {
    if(e.state && e.state.startsWith('#') && $(e.state).length){
      $('html, body').animate({scrollTop: $(e.state).offset().top}, 500)
    }
  });

  $('html, body').on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
    $('html, body').stop();
  });

如果用户在动画播放期间开始滚动(使用鼠标滚轮),滚动将被取消以避免与动画发生冲突。

尽管动画会替换click事件,但由于使用了JavaScript历史API,hash仍然会被添加到URL中,浏览器的前进或后退按钮仍然可以工作。

图标由Dave Gandy制作,来自www.flaticon.com

Piotr Pogorzelski提供。