给Hexo博客文章加上朗读播放器

具体步骤

1. 取消注释这一行_config.next.yml 里去掉前面的 #):

1
2
custom_file_path:
postMeta: source/_data/post-meta.njk

2. 新建文件 source/_data/post-meta.njk(注意路径是相对于你博客根目录,不是主题目录):

1
2
3
4
5
{% if page.layout === 'post' %}
<span class="post-meta-item">
<i id="tts-toggle-btn" class="fa fa-volume-up tts-icon" onclick="toggleSpeak()" title="朗读本文" style="cursor:pointer;"></i>
</span>
{% endif %}

3. JS 逻辑放进 bodyEnd(同样在这个 _config.next.yml 里取消注释):

1
2
3
custom_file_path:
postMeta: source/_data/post-meta.njk
bodyEnd: source/_data/body-end.njk

新建 source/_data/body-end.njk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script>
let ttsSpeaking = false;

function toggleSpeak() {
const btn = document.getElementById('tts-toggle-btn');

if (ttsSpeaking) {
// 当前正在朗读 -> 停止
speechSynthesis.cancel();
ttsSpeaking = false;
btn.classList.remove('fa-stop');
btn.classList.add('fa-volume-up');
btn.title = '朗读本文';
} else {
// 当前未朗读 -> 开始
const content = document.querySelector('.post-body').innerText;
const utterance = new SpeechSynthesisUtterance(content);
utterance.lang = 'zh-CN';
utterance.rate = 1;

// 朗读自然结束时,图标自动切回播放状态
utterance.onend = () => {
ttsSpeaking = false;
btn.classList.remove('fa-stop');
btn.classList.add('fa-volume-up');
btn.title = '朗读本文';
};

speechSynthesis.speak(utterance);
ttsSpeaking = true;
btn.classList.remove('fa-volume-up');
btn.classList.add('fa-stop');
btn.title = '停止朗读';
}
}
</script>

4. 加点 CSS 微调source/_data/styles.styl):

1
2
3
4
5
6
7
.tts-icon {
color: #808080;
transition: color 0.2s;
}
.tts-icon:hover {
color: #49b1f5; /* NexT 默认主题色,可按你的实际配色调整 */
}