参考教程
优化步骤
Pjax能够实现页面的局部刷新而非整体重载资源,在一定程度上能够减少网站反复加载重复资源,从而优化访问体验。
博主目前使用的是
Butterfly
主题,而最新版Butterfly
主题已经将该教程方案集成在主题中。只需在主题配置文件中搜索pjax,将其enable
参数设置为true
即可开启。重载第三方js
在魔改主题时,肯定会不可避免的添加一系列第三方js,此时就会遇到切换页面后,由于通过 Pjax切换的页面并没有完全刷新,浏览器不会将网页从头执行一遍,因此有些JS将不会生效。
得益于Butterfly
已经将解决方案集成在[Blogroot]\themes\butterfly\layout\includes\third-party\pjax.pug
文件下。1
2
3$('script[data-pjax]').each(function () {
$(this).parent().append($(this).remove())
})1
2
3
4
5
6
7document.querySelectorAll('script[data-pjax]').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
})这个函数会对在script标签中添加了
data-pjax
属性的的js,在页面切换后执行重载,达到局部刷新的效果。
所以我们要做的事情十分简单,给这些js引入的位置添加data-pjax
属性即可。1
2
3
4
5
6
7
8
9inject:
head:
# 首页电子钟
- <link rel="stylesheet" href="/clock/css/clock.css"/>
bottom:
# 首页电子钟
- <script src="/clock/js/vue.min.js"></script>
- - <script src="/clock/js/clock.js"></script>
+ - <script data-pjax src="/clock/js/clock.js"></script>使用data-pjax的过程中,务必考虑到变量被反复声明的问题。例如在clock.js中,有用const定义了api密钥的常量,但是添加data-pjax之后,切换页面时会反复声明这个常量。和const的生命周期起冲突。解决方案有(以下方案二选一即可,全部都做反而有bug)
- 把声明常量的代码放到单独的js中,并且不加data-pjax。
- 将const声明改成用let或者var声明。
如果不是在主题配置文件的inject中引入,而是通过在特定页面写入,可能不方便在标签处直接添加
data-pjax
属性,参考教程中有给出解决方案。
可以修改[Blogroot]\themes\butterfly\layout\includes\third-party\pjax.pug
的内容。给他多加一个选择器。(实质其实就是第4步的变种,可以跳过第3步直接参考第4步)旧版方案
此处修改的是特定选择器,必须是
pjax-reload
下的第一个script
标签才行。并不是很方便多行插入。请看新版方案。1
2
3
4- $('script[data-pjax]').each(function () {
+ $('script[data-pjax], .pjax-reload script').each(function () {
$(this).parent().append($(this).remove())
})1
2
3
4
5
6
7
8- document.querySelectorAll('script[data-pjax]').forEach(item => {
+ document.querySelectorAll('script[data-pjax], .pjax-reload script').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
})然后将你需要重载的JS方法函数名或者JS片段用
<div class="pjax-reload"></div>
包裹起来。此处以butui.js为例。1
2
3
4
5
6
7- <script src="/js/botui.js"></script>
+ <script data-pjax src="/js/botui.js"></script>
+ <div class="pjax-reload">
<script>
bot_ui_ini()
</script>
+ </div>新版方案
在
butterfly
主题中,有按照第4步中所述,在pjax选择器
中添加了.js-pjax
的类名,也就是说,只要是在类名为js-pjax
元素包裹下的内容就会执行局部重载。- 网页写法
1
2
3
4
5
6<div class="js-pjax">
<script>
bot_ui_ini()
// 可以是函数引用,可以是代码片段。甚至可以是任何需要重载的网页元素。
</script>
</div> - pug写法
1
2
3
4.js-pjax
script.
bot_ui_ini()
// 可以是函数引用,可以是代码片段。甚至可以是任何需要重载的网页元素。 - markdown写法,同html写法,此处加上
raw
标签是为了告诉渲染引擎这段不需要渲染。1
2
3
4
5
6
7
8{% raw %}
<div class="js-pjax">
<script>
bot_ui_ini()
// 可以是函数引用,可以是代码片段。甚至可以是任何需要重载的网页元素。
</script>
</div>
{% endraw %}
- 网页写法
集成在插件中的js
集成在插件中的js是最难办的,它们往往是通过在页面中使用添加了
指定id
的div
等标签界定位置,然后由插件去渲染。我们按照上面的方法给这些静态标签
添加pjax重载
毫无意义。毕竟要重载的起码得是个js才行。可以考虑使用最新版Butterfly主题自带的pjax屏蔽设置(不推荐)。
1
2
3
4
5
6
7pjax:
- enable: false
+ enable: true
exclude:
+ - /artitalk/
+ - /about/
# 此处填页面的相对路径。但是这样子一来,如果有添加
Aplayer
的全局音乐或其他全局配置的话,会在切换到屏蔽了Pjax
的页面时被强制刷新,不符合流畅的用户体验。那就只能修改源码了。此处以
HCLonely
开发的hexo-charts
插件为例。插件中用特定id
的div
标签作为定位。1
2
3
4
5
6<!-- 发布文章统计图 -->
<div id="posts-chart"></div>
<!-- 文章标签统计图 -->
<div id="tags-chart" data-length="10"></div>
<!-- 文章分类统计图 -->
<div id="categories-chart"></div>那么给它们添加
pjax
,就需要在pjax选择器
中添加这几个id
,找到[Blogroot]\themes\butterfly\layout\includes\third-party\pjax.pug
中的pjaxSelectors
。添加需要局部刷新的标签类。写法类似css
选择器。1
2
3
4
5
6
7
8
9
10
11
12script.
let pjaxSelectors = [
'title',
'#config_change',
'#body-wrap',
'#rightside-config-hide',
'#rightside-config-show',
+ '#posts-chart',
+ '#tags-chart',
+ '#categories-chart',
'.js-pjax'
]
pjax
、pwa
、gulp
堪称BUG御三家,请在使用前做好心理准备。啊咧咧,温馨提示放最后会不会有点戏耍读者的意思。
Use this card to join the candyhome and participate in a pleasant discussion together .
Welcome to 测试's candyhome,wish you a nice day .