0

0

利用 Paged.js 动态生成带页码的目录

聖光之護

聖光之護

发布时间:2025-11-28 15:12:22

|

1025人浏览过

|

来源于php中文网

原创

利用 paged.js 动态生成带页码的目录

本文详细介绍了如何使用 Paged.js 结合 JavaScript 动态生成 HTML 文档的目录(Table of Contents),并自动填充页码。通过定制 Paged.js 的处理器,在内容解析前构建目录结构,然后利用 CSS target-counter 功能实现页码的自动显示,解决了在打印布局中获取元素页码的挑战。

引言:动态目录与 Paged.js 的挑战

在将 HTML 内容转换为可打印的文档时,生成一个带有准确页码的动态目录是一个常见需求。传统的做法是手动更新页码,但这在内容变动时效率低下且易出错。使用像 Paged.js 这样的工具可以自动化这一过程,但直接通过 JavaScript 或 jQuery 访问 DOM 元素来获取其在最终打印布局中的页码并非易事,因为页码是 Paged.js 渲染引擎在布局阶段计算出来的。

本文将深入探讨如何利用 Paged.js 的强大功能,通过其生命周期钩子和 JavaScript 编程,实现一个完全动态且带有页码的目录生成方案。

核心机制:利用 Paged.js 的生命周期钩子

Paged.js 提供了一套生命周期钩子,允许开发者在文档处理的不同阶段介入。对于动态目录生成,最合适的钩子是 beforeParsed。在这个阶段,Paged.js 已经加载了 HTML 内容,但尚未进行布局和分页处理。这意味着我们可以在此时遍历文档中的标题元素,构建目录结构,并为它们添加必要的属性,为后续的页码显示做准备。

Paged.Handler 是 Paged.js 中用于扩展其功能的基类。通过创建一个继承自 Paged.Handler 的自定义类,并重写 beforeParsed 方法,我们可以在 Paged.js 开始解析内容之前执行自定义逻辑。

构建目录结构:JavaScript 实现

动态目录的构建主要通过一个 JavaScript 函数完成,该函数负责识别文档中的标题,为它们生成唯一的标识符(如果不存在),并构建一个链接到这些标题的目录列表。

HTML 基础结构

首先,我们需要在 HTML 文档中定义标题元素和目录的占位符。标题应具有清晰的结构,例如使用

,

等。目录占位符通常是一个空的
    ,它将通过 JavaScript 填充。
    
    

    前数字时代

    此处是章节内容...

    数字时代

    此处是章节内容...

    请注意,为标题添加 id 属性至关重要,因为目录中的链接( 标签的 href 属性)将指向这些 ID。如果标题没有 ID,我们的 JavaScript 函数会为其自动生成。

    createToc 函数详解

    createToc 函数是实现动态目录的核心。它接收一个配置对象,包含内容的根元素、目录占位符的选择器以及标题元素的选择器数组。

    野羊分类信息系统
    野羊分类信息系统

    ===更新说明==解决了无法登陆后台的问题!完善了部分功能修复了一个BUG..修改静态模版说明:本系统的首页 和 内容页 不支持动态显示,需要生成HTML(实为.asp文件)模版文件存放在temp目录下index.html为首页模版show.html为内容页模版......=============2007 - 10 - 20 ===========注:1*使用前请务必修改 inc/conn.as

    下载
    function createToc(config) {
      const content = config.content; // 文档内容根元素
      const tocElementSelector = config.tocElement; // 目录占位符选择器
      const titleElementsSelectors = config.titleElements; // 标题元素选择器数组
    
      // 获取目录占位符元素,并创建一个无序列表作为目录容器
      let tocElementDiv = content.querySelector(tocElementSelector);
      let tocUl = document.createElement("ul");
      tocUl.id = "list-toc-generated";
      tocElementDiv.appendChild(tocUl);
    
      // 遍历所有指定标题元素,确保它们有ID并添加辅助类
      let tocElementNbr = 0;
      for (let i = 0; i < titleElementsSelectors.length; i++) {
        let titleHierarchy = i + 1; // 根据选择器数组的顺序确定层级
        let titleElements = content.querySelectorAll(titleElementsSelectors[i]);
    
        titleElements.forEach(function (element) {
          // 添加通用类和层级数据属性
          element.classList.add("title-element");
          element.setAttribute("data-title-level", titleHierarchy);
    
          // 如果元素没有ID,则生成一个唯一ID
          tocElementNbr++;
          if (element.id === "") {
            element.id = "title-element-" + tocElementNbr;
          }
        });
      }
    
      // 根据已处理的标题元素创建目录列表项
      let processedTocElements = content.querySelectorAll(".title-element");
    
      for (let i = 0; i < processedTocElements.length; i++) {
        let tocElement = processedTocElements[i];
    
        let tocNewLi = document.createElement("li");
    
        // 为目录列表项添加层级类
        tocNewLi.classList.add("toc-element");
        tocNewLi.classList.add(
          "toc-element-level-" + tocElement.dataset.titleLevel
        );
    
        // 复制标题元素的其他类到目录列表项(可选)
        let classTocElement = tocElement.classList;
        for (let n = 0; n < classTocElement.length; n++) {
          if (classTocElement[n] !== "title-element") {
            tocNewLi.classList.add(classTocElement[n]);
          }
        }
    
        // 创建链接,href指向标题ID,文本内容为标题内容
        tocNewLi.innerHTML =
          '' + tocElement.innerHTML + "";
        tocUl.appendChild(tocNewLi);
      }
    }

    函数参数说明:

    • config.content: Paged.js 传递的文档内容根元素,通常是 或其子元素。
    • config.tocElement: 目录占位符的 CSS 选择器,例如 "#my-toc-content"。
    • config.titleElements: 一个字符串数组,每个字符串是一个 CSS 选择器,用于匹配不同层级的标题元素,例如 ["h1", "h2", "h3"]。

    工作流程:

    1. 初始化目录容器: 查找目录占位符,并在其中创建一个新的
        元素。
    2. 处理标题元素: 遍历 titleElementsSelectors 数组中的每个选择器。
      • 对于每个匹配的标题元素,为其添加 title-element 类和 data-title-level 属性,后者指示其在目录中的层级。
      • 如果标题元素没有 id 属性,则为其生成一个唯一的 ID。这是确保目录链接可用的关键。
    3. 生成目录列表: 再次遍历所有带有 title-element 类的标题元素。

    集成到 Paged.js 工作流

    createToc 函数本身只是一个独立的 JavaScript 函数。为了让它在 Paged.js 处理文档时自动运行,我们需要将其封装在一个 Paged.Handler 中,并在 beforeParsed 钩子中调用它。

    将以下代码添加到 HTML 文档的

    部分,紧随 Paged.js 脚本之后:
    
    

    在这个示例中,CustomTocHandler 是我们自定义的 Paged.js 处理器。在 beforeParsed 方法中,我们调用 createToc 函数,并传入 Paged.js 提供的 content 对象(代表了待处理的整个文档内容),以及目录占位符和标题选择器。

    显示页码:CSS 与 target-counter

    上述 JavaScript 代码完成了目录结构的构建,将标题链接到其对应的位置。然而,它并没有直接在目录中插入页码。页码的显示是 Paged.js 结合 CSS target-counter 功能来实现的。

    target-counter() 是一个 CSS 函数,它允许你获取文档中某个元素在特定命名计数器(如 page 计数器)上的值。当与目录链接的 href 属性结合使用时,它就能显示链接目标元素的页码。

    通常,你会在 CSS 中这样定义页码的显示:

    @page {
      /* 定义页码计数器 */
      counter-increment: page;
      @bottom-right {
        content: counter(page); /* 在页面底部显示当前页码 */
      }
    }
    
    /* 为目录列表项添加页码 */
    .toc-element a::after {
      content: target-counter(attr(href), page); /* 显示链接目标元素的页码 */
      float: right; /* 将页码浮动到右侧 */
      margin-left: 1em; /* 与标题文字保持距离 */
    }

    通过这种 CSS 规则,当 Paged.js 渲染文档时,它会自动计算每个标题的页码,并通过 target-counter(attr(href), page) 将其注入到目录 标签的 ::after 伪元素中。

    注意事项与最佳实践

    1. HTML 结构清晰: 确保你的 HTML 标题结构(

      ,

      等)是语义化的,这有助于 createToc 函数准确识别目录项。

  • ID 的唯一性: 尽管 createToc 会为没有 ID 的标题生成 ID,但最好在编写 HTML 时就为关键标题提供有意义且唯一的 ID,以提高可读性和维护性。
  • CSS 选择器的准确性: 在 createToc 的 titleElements 配置中,使用精确的 CSS 选择器来匹配你希望包含在目录中的标题。
  • Paged.js 依赖: 确保 Paged.js 库已正确加载到你的 HTML 文档中。
  • 调试: 在开发过程中,可以使用浏览器的开发者工具检查生成的目录结构和 Paged.js 的控制台输出,以便调试任何问题。
  • 样式定制: 利用 toc-element 和 toc-element-level-N 等类,你可以通过 CSS 对生成的目录进行精细的样式控制,例如缩进、字体大小等。
  • 总结

    通过 Paged.js 的 beforeParsed 钩子和自定义 JavaScript 函数,我们可以高效地动态生成 HTML 文档的目录。JavaScript 负责构建目录的结构和链接,而 Paged.js 结合 CSS target-counter 则负责在打印布局中自动填充正确的页码。这种方法不仅解决了手动更新页码的痛点,也使得内容更新和布局调整变得更加灵活和自动化,极大地提升了可打印文档的生成效率和用户体验。

    相关专题

    更多
    js获取数组长度的方法
    js获取数组长度的方法

    在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

    554

    2023.06.20

    js刷新当前页面
    js刷新当前页面

    js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

    374

    2023.07.04

    js四舍五入
    js四舍五入

    js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

    731

    2023.07.04

    js删除节点的方法
    js删除节点的方法

    js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

    477

    2023.09.01

    JavaScript转义字符
    JavaScript转义字符

    JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

    394

    2023.09.04

    js生成随机数的方法
    js生成随机数的方法

    js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

    990

    2023.09.04

    如何启用JavaScript
    如何启用JavaScript

    JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

    656

    2023.09.12

    Js中Symbol类详解
    Js中Symbol类详解

    javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

    551

    2023.09.20

    Golang gRPC 服务开发与Protobuf实战
    Golang gRPC 服务开发与Protobuf实战

    本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

    8

    2026.01.15

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Sass 教程
    Sass 教程

    共14课时 | 0.8万人学习

    Bootstrap 5教程
    Bootstrap 5教程

    共46课时 | 2.9万人学习

    CSS教程
    CSS教程

    共754课时 | 19.2万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号