每次后台写完一篇文章时都不清楚写了多少字,合计着需要给编辑器加个字数统计功能了。为了方便打字时实时了解敲了多少,决定在前端通过 JavaScript 来实现。
需求分析
功能从流程上来说很简单,只需要监听编辑器的 change
事件,然后获取最新内容,并统计字数,然后把字数输出到一个指定的位置就可以了。实际做的时候发现有一些关键点是需要注意的。
首先从需求上来说,就可以排除 JavaScript 字符串提供的 length
属性。这个属性提供的是字符串的长度,并不能代表字数。比如 「有 1 天」这条字符串,用 length
会返回 5,它把中间的空格也计算在内。所以要获取准确的字数只能自己按要求来计算。
我的要求比较简单,只需要统计中文和英文就可以了。中文用排除标点符号后的字数,英文使用空格区分每个单词,一个单词算一个字。数字当成英文一样处理。来看看如何实现。
统计中文字数
我定义了一个统计字数的方法。监听编辑器并获取最新内容拿到编辑器的内容后,把内容作为传参调用这个方法就可以得到字数。这是包含了统计中文字数功能的方法代码:
const countWords = (text) => {
const total = {
cn: 0, // 中文字数
en: 0, // 英文字数
}
// 获取中文字数
let tmp = text.match(/\p{sc=Han}/gu);
if (tmp) {
total.cn = tmp.length
}
return total;
}
通过一个特殊的正则匹配,搞定了汉字字数的统计。
统计英文字符
在中文统计代码后追加下面的代码:
...
// 获取英文字数
tmp = text.replace(/[^\w-]/g, ' ')
tmp = tmp.split(/\s+/)
tmp = tmp.filter(w => {
return ['', '-', '_'].indexOf(w.trim()) === -1
})
total.en = tmp.length
...
英文字数以单词区分,需要保留空格位置,所以稍微多了两步流程。先要通过空格区分单词,然后还要清除多余的空格,这样才能确保统计的字数是有效的。
最后只需要获取这个字数统计方法返回值中的 cn
和 en
属性,它们分别代表了内容中的中文字数和英文字数。两者相加就是最终文章的总字数了。