以下由Hugo的stack主题演示,其他的可作为参考。
修改方法来源:莱特雷-letere
引入APlayer
-
在Hugo工作文件夹的
layouts/partials/footer文件夹中新建一个文件,命名为aplayer.html。 -
在
aplayer.html中输入以下内容:
1<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
2<div id="aplayer"></div>
3<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
4
5<script>
6 const ap = new APlayer({
7 container: document.getElementById('aplayer'),
8 fixed: true,
9 listFolded: true,
10 lrcType: 3,
11 audio: [{
12 name: 'example',
13 artist: 'example',
14 url: 'https://example.mp3',
15 lrc: 'example.lrc',
16 cover: 'example.png'
17 }]
18 });
19</script>
- 在
layouts/partials/footer中新建一个文件夹,命名为custom.html,在其中输入:
1{{ partialCached "footer/aplayer.html" . }}
这样,aplayer就成功导入到网页中了。
修改APlayer样式
实现播放进度保存
1<script>
2 /**
3 * 页面销毁前监听
4 */
5 window.onbeforeunload = () => {
6 // 将播放信息用对象封装,并存入到localStorage中
7 const playInfo = {
8 index: ap.list.index,
9 currentTime: ap.audio.currentTime,
10 paused: ap.paused
11 };
12 localStorage.setItem("playInfo", JSON.stringify(playInfo));
13 };
14
15 /**
16 * 页面加载后监听
17 */
18 window.onload = () => {
19 // 从localStorage取出播放信息
20 const playInfo = JSON.parse(localStorage.getItem("playInfo"));
21 if (!playInfo) {
22 return;
23 }
24 // 切换歌曲
25 ap.list.switch(playInfo.index);
26 // 等待500ms再执行下一步(切换歌曲需要点时间,不能立马调歌曲进度条)
27 setTimeout(() => {
28 // 调整时长
29 ap.seek(playInfo.currentTime);
30 // 是否播放
31 if (!playInfo.paused) {
32 ap.play()
33 }
34 }, 500);
35 };
36</script>
实现隐藏播放器图标
1<style>
2 .aplayer-fixed.aplayer-narrow .aplayer-body {
3 left: -70px !important;
4 /* 默认情况下缩进左侧70px,只留一点箭头部分 */
5 }
6
7 .aplayer-fixed.aplayer-narrow .aplayer-body:hover {
8 left: 0 !important;
9 /* 鼠标悬停是左侧缩进归零,完全显示按钮 */
10 }
11</style>
导入pjax实现音乐不间断播放
pjax是一项页面切换不加载技术,可实现切换网页后音乐不间断。
导入pjax
-
在
layouts/partials/footer中新建文件,命名为pjax.html. -
在文件中写入代码:
1<script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script>
2<script>
3 var pjax = new Pjax({
4 selectors: [
5 ".main-container"
6 ]
7 })
8</script>
这样pjax就成功导入网页中了。
修复网页样式
在pjax.html中加入以下内容:
1<script>
2 pjax._handleResponse = pjax.handleResponse;
3 pjax.handleResponse = function(responseText, request, href, options) {
4 if (request.responseText.match("<html")) {
5 if (responseText) {
6 // 将新页面的html字符串解析成DOM对象
7 let newDom = new DOMParser().parseFromString(responseText, 'text/html');
8 // 获取新页面中body的className,并设置回当前页面
9 let bodyClass = newDom.body.className;
10 document.body.setAttribute("class", bodyClass)
11 // 放行,交给pjax自己处理
12 pjax._handleResponse(responseText, request, href, options);
13 }
14 } else {
15 // handle non-HTML response here
16 }
17 }
18</script>
修复主题切换
在pjax.html中加入以下内容。
1<script>
2 document.addEventListener('pjax:complete', () => {
3 // Stack脚本初始化
4 window.Stack.init();
5 })
6</script>
修复搜索
- 修改
assets/ts/search.tsx代码,封装方法并export
1/**
2 * 记得把window.addEventListener('load' ...这部分代码注释掉
3 * 初始化工作交给Stack.init()处理了,不需要这个了
4 */
5...
6function searchInit() {
7 let search = document.querySelector('.search-result');
8 if (search) {
9 const searchForm = document.querySelector('.search-form') as HTMLFormElement,
10 searchInput = searchForm.querySelector('input') as HTMLInputElement,
11 searchResultList = document.querySelector('.search-result--list') as HTMLDivElement,
12 searchResultTitle = document.querySelector('.search-result--title') as HTMLHeadingElement;
13
14 new Search({
15 form: searchForm,
16 input: searchInput,
17 list: searchResultList,
18 resultTitle: searchResultTitle,
19 resultTitleTemplate: window.searchResultTitleTemplate
20 });
21 }
22}
23
24export {
25 searchInit
26}
- 修改
assets/ts/main.ts,引入搜索初始化方法并调用
1...
2import { searchInit } from "ts/search";
3let Stack = {
4 init: () => {
5 ...
6 // 调用search脚本初始化方法
7 searchInit();
8 }
9}
-
tsx 类型的文件引入方式有点特殊,需要我们修改
main.ts的引入方式,修改layouts/partials/footer/components/script.html,改法参考layouts/page/search.html,把JSXFactory,createElement补充上就好 -
修改
assets/ts/search.tsx,在动态渲染数据方法末尾让pjax重新解析文档
1private async doSearch(keywords: string[]) {
2 ...
3 /*
4 方法末尾,让pjax重新解析文档数据,识别动态渲染的数据
5 虽然当前文件没有pjax对象,但最后静态页面会生成一个整体的js文件
6 pjax对象那时就能识别到,就可成功调用
7 */
8 pjax.refresh(document);
9}
修复Latex
- 修改
layouts/partials/article/components/math.html,添加一个元素标签,便于判断文档是否使用了KaTeX
1<div class="math-katex"></div>
- 在
layouts/partials/footer/custom.html中引入以下代码:
1<script>
2 async function renderKaTeX() {
3 // 判断当前页面是否有KateX
4 let katex = document.querySelector(".math-katex");
5 if (!katex) {
6 return;
7 }
8 // 等待函数加载成功后,再执行渲染方法
9 while (typeof renderMathInElement !== 'function') {
10 await delay(500);
11 }
12 // KaTeX渲染方法
13 renderMathInElement(document.body, {
14 delimiters: [
15 { left: "$$", right: "$$", display: true },
16 { left: "$", right: "$", display: false },
17 { left: "\\(", right: "\\)", display: false },
18 { left: "\\[", right: "\\]", display: true }
19 ],
20 ignoredClasses: ["gist"]
21 });
22 }
23
24 /**
25 * 同步延迟
26 */
27 function delay(time) {
28 return new Promise(resolve => {
29 setTimeout(resolve, time)
30 })
31 }
32
33 document.addEventListener('pjax:complete', () => {
34 renderKaTeX();
35 })
36</script>
取消pjax的时间戳
pjax会默认给网页加上时间戳,具体为表现为?t=1724141234567的样式,这样会使页面间的跳转出现问题,建议关闭。
在pjax.html中引入:
1<script>
2 document.addEventListener('DOMContentLoaded', function () {
3 if (window.pjax) {
4 window.pjax.options.cacheBust = false; // 关闭时间戳参数
5 }
6 });
7</script>