前言:
- 这是从 【Hugo】Aplayer + PJAX 引入音乐播放放器并实现音乐不中断功能 中单独摘出的内容,内容一模一样
- 单独开一篇新文章,用来更新引入PJAX带来的问题,就不更新在音乐播放器那篇文章上了
- 此教程是基于Stack-3.26.0,不确保其他版本是否生效,若不生效请自行阅读源码修复
1 引入PJAX
- (1)PJAX主要分为两个版本,带JQuery 和 不带JQuery的,下面我演示的是不带JQuery版本的
- 【defunkt/jquery-pjax】(带JQuery)
- 【MoOx/pjax】(不带JQuery)
- (2)分析页面元素,看哪些是需要我们重新加载的,可以发现是左侧边栏,中间内容,右侧边栏
- (3)查看页面源代码,可以发现这些元素都被一个
<div class="main-container">...</div>
包裹着,所以我们将这元素定为要刷新的对象
- (4)根据官方文档,在
layouts/partials/footer/custom.html
加入以下代码来引入PJAX
|
|
这样算是已经基本引入了PJAX,但也带来了不少问题,我们一步一步进行修复
2 问题修复
2.1 文章样式修复
- 问题描述:
- 随便点进其中一篇文章,可以发现文章内容的样式丢失
- 产生原因:
<body>
标签中的class名缺失article-page,导致文章样式丢失
- 解决思路:
- 通过官方提供了数据预处理方法,来预处理数据,获取到新页面的className,然后我们手动将这className设置到
<body>
上
- 通过官方提供了数据预处理方法,来预处理数据,获取到新页面的className,然后我们手动将这className设置到
- 具体步骤:
- (1)修改
layouts/partials/footer/custom.html
,引入以下代码
|
|
2.2 主题切换修复
- 问题描述:
- 当我们切换页面后,点击左下角切换主题颜色的按钮,会发现没有效果,主题颜色切换失效了
- 产生原因:
- 阅读Stack主题源码
assets/ts/colorScheme.ts
发现,在脚本初始化时,会给元素绑定一个点击事件。但因为页面切换了,替换了该元素,但该元素没有重新绑定点击事件,导致点击主题切换失效
- 阅读Stack主题源码
- 解决思路:
- 在PJAX切换完页面后,重新执行一遍
colorScheme.ts
的初始化,使元素重新绑定点击事件。 - 阅读源码,发现
colorScheme.ts
被main.ts
引用,在main.ts
中执行了初始化,并且main.ts
生成了个全局变量 Stack - 所以在PJAX执行完后,使用全局变量 Stack ,执行里面的初始化方法,重新执行一遍脚本,来绑定点击事件
- 阅读PJAX文档,发现官方也提供了PJAX执行完后的事件,我们执行监听这个事件,Stack 执行初始化就好
- 在PJAX切换完页面后,重新执行一遍
- 具体步骤:
- (1)修改
layouts/partials/footer/custom.html
,引入以下代码
|
|
2.3 文章搜索修复
- 问题描述:
- 使用文章搜索功能时,输入关键词,无任何搜索记录,搜索功能失效
- 产生原因:
- 查看
assets/ts/search.tsx
文件,发现情况和上面的colorScheme.ts
类似,存在绑定事件
- 查看
- 解决思路:
- 把 search.tsx 初始化内容,封装为一个函数,并把函数 export 出来
- 由 main.ts 引入这个函数,并放到 Stack.init() 的方法中,利用此方法来重新初始化搜索脚本
- 具体步骤:
- (1)修改
assets/ts/search.tsx
代码,封装方法并export
|
|
- (2)修改
assets/ts/main.ts
,引入搜索初始化方法并调用
|
|
- (3)tsx 类型的文件引入方式有点特殊,需要我们修改以下 main.ts 的引入方式,修改
layouts\partials\footer\components\script.html
,改法参考layouts\page\search.html
,把"JSXFactory" "createElement"
补充上就好
2.4 搜索内容跳转修复
- 问题描述:
- 虽然文章搜索已经修复了,但搜索出来的内容并没有被PJAX识别到,导致PJAX没有拦截,进而导致页面刷新了
- 产生原因:
- 阅读 search.tsx 源码可知,搜索内容的数据,是通过 React.render() ,动态渲染回页面的,这些动态数据没有被PJAX识别到。
- 解决思路:
- 阅读PJAX文档,官方提供给了我们重新解析数据的方法,所以在 React.render() 之后,调用PJAX方法,重新解析页面即可
- 具体步骤:
- (1)修改
assets/ts/search.tsx
,在动态渲染数据方法末尾让pjax重新解析文档
|
|
2.5 文章评论修复
- 问题描述:
- 如果博客有开启评论功能的话,会发现评论的脚本不生效了
- 产生原因:
- pjax引入自动执行的脚本,不支持自行执行
- 解决思路:
- 由于每个人使用的评论种类各不相同,所以这边也是简单说一下。PJAX官方文档也有说如何处理:
- 用一个
<div class=js-Pjax></div>
来包裹一个<script></script>
- 在
<script>
标签中,通过document.createElement('script')
形式,创建对应的评论脚本内容 - pjax对象通过 .js-Pjax 被识别到此内容,进行脚本执行
- 具体步骤:
- (1)修改
layouts/partials/footer/custom.html
,把实际的评论参数填写进行下面模板
|
|
2.6 KaTeX修复
- 问题描述:
- 点进含有 数学公式(KaTeX) 的文章,里面的数学公式不能正常渲染出来
$\varphi = \dfrac{1+\sqrt5}{2}= 1.6180339887…$
- 产生原因:
- 阅读源码
layouts/partials/article/components/math.html
,KaTeX渲染公式需要执行renderMathInElement,而PJAX的无刷新技术无法触发DOMContentLoaded的监听
- 阅读源码
- 解决思路:
- 将KaTeX渲染方法renderMathInElement封装为函数,交由PJAX加载结束后执行
- 具体操作:
- (1)修改
layouts/partials/article/components/math.html
,添加一个元素标签,便于判断文档是否使用了KaTeX
|
|
- (2)
layouts/partials/footer/custom.html
,引入以下代码
|
|
3 引入进度条
-
(1)由于使用了PJAX后,无法得知页面的加载情况是否完成,所以引入一个伪进度条,来显示页面内容进度
-
(2)前往【topbar】,点击下载zip包,将解压后的 topbar.min.js 放到
assets\js\topbar.min.js
-
(3)通过监听PJAX两个事件 pjax:send 和 pjax:complete 实现伪进度条
|
|
这样伪进度条就成功引入了,能大概知道页面的加载情况了