Halo 的文章字数统计实现
开发 Halo 主题时,想为文章添加字数统计显示,在 Halo 的文档中没有找到相关实现,查询 GitHub 仓库,发现之前有过该功能:
- 统计下文章字数,方便前台调用 · Issue #884 · halo-dev/halo
- 无法统计文章字数 · Issue #1005 · halo-dev/halo
- Halo有没有统计字数的功能呀 - Halo 社区
- 文章字数统计考虑英文单词计数 · Issue #1759 · halo-dev/halo
但不知为何后来又删除了:
- 关于MarkDown类型的文章字数显示异常 · Issue #3542 · halo-dev/halo
- halo 中自建页面字数统计有问题。 · Issue #6560 · halo-dev/halo
目前只能考虑在主题中自行实现。有两种方案:
-
根据文章内容
$post.content.content
,通过 Thymeleaf 的#strings.length()
方法计算字符串长度作为文章字数<span th:text="${#strings.length(post.content.content)}"></span>
问题在于,
$post.content.content
是带 HTML 标签的原始内容,比文章的实际文字内容会多出不少字符计数。同时计算字符串长度的算法,对中文是计算汉字数,但对英文是计算字母数,而不是单词数。以这篇文章为例,如此统计的字数为 4603,实际字数为 679。 -
由 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 计算字数,没有持久化存储,可能会影响加载延迟。