Halo 的文章字数统计实现
技术 Halo 79

开发 Halo 主题时,想为文章添加字数统计显示,在 Halo 的文档中没有找到相关实现,查询 GitHub 仓库,发现之前有过该功能:

但不知为何后来又删除了:

目前只能考虑在主题中自行实现。有两种方案:

  1. 根据文章内容 $post.content.content​,通过 Thymeleaf 的 #strings.length()​ 方法计算字符串长度作为文章字数

    <span th:text="${#strings.length(post.content.content)}"></span>
    

    问题在于,$post.content.content​ 是带 HTML 标签的原始内容,比文章的实际文字内容会多出不少字符计数。同时计算字符串长度的算法,对中文是计算汉字数,但对英文是计算字母数,而不是单词数。以这篇文章为例,如此统计的字数为 4603,实际字数为 679。

  2. 由 JavaScript 在前端获取文章主体元素的 textContent.length​ 作为文章字数并渲染到 HTML 中

    <!-- 字数  -->
    <span id="post-wordcount"></span>
    
    <!-- 文章主体  -->
    <div id="post-content" th:utext="${post.content.content}"></div>
    
    document.addEventListener("DOMContentLoaded", function () {
      // 获取指定的元素
      const element = document.querySelector("#post-content");
      // 计算字数
      const textLength = element.textContent.length;
      // 将字数显示在 HTML 中
      document.getElementById("post-wordcount").textContent = textLength;
    });
    

    textContent​ 不包含 HTML 标签,虽然不是文章的实际文字内容,但已经准确不少了,当然计算字符串长度的算法对于英文的问题依然存在。以同样的文章为例,如此统计的字数为 687,实际字数为 679。

    此外,因为每次加载文章时都会调用 JavaScript 计算字数,没有持久化存储,可能会影响加载延迟。