文章目录
  1. 1. 与其他成功案例进行比较
  2. 2. 找到整页刷新的问题关键
  3. 3. 修复失效、报错的脚本
  4. 4. 加入网易云播放器
  5. 5. 总结

每天事情多得要命,全靠2毛一袋的咖啡和 精神氮泵 续命。所谓精神氮泵,自然是来自网易云音乐的给力歌曲了。

我的精神氮泵

一直想整合网页版播放器到博客里跟大家一起嗨。但是放在博客里是必须要改造目前的博客,如果不进行改造,跳转页面肯定会引起播放器中断。1月份的时候尝试利用 Pjax 的特性(尝试改造Hexo主题以兼容Pjax),局部加载核心内容,而不影响播放器,可惜失败了。不过我这个人有个毛病,就是总会反复做一些事情。不信邪的我又翻出 Pjax 来研究了,别人都可以用,我相信一定有方法可以用上。

当然,这次不一样。我成功了!

与其他成功案例进行比较

我最终找到了 t0ur1st 的博客作为对比目标进行分析。首先跟我之前最大的区别是我使用了独立版的 Pjax

1
<script src="https://cdn.jsdelivr.net/npm/pjax@VERSION/pjax.min.js"></script>

然而他使用了jquery版本:

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>

既然Gacman主题本来就用到了 jQuery ,人家都已经成功了,何必还要去折腾呢?我选择躺平!

找到整页刷新的问题关键

Gacman主题继承自已经废弃的老版Jacman主题,各个模板之间的确都有些不太一样。模板不同的确会给 Pjax 改造带来一些困难,但我的Gacman其实已经大幅统一了,十分符合只更新核心部分、不更新页头/页脚和侧边栏的需求,所以不应该有这种阻碍才对。

通过一番寻找,最大的问题就是在改造响应式风格的时候,layout.ejs 对于body模块内容的适配太零散了,分别在 article.ejs 等模板里单独做了嵌套结构和样式适配。而对于我这个模板来说,其实完全可以统一起来。于是 layout.ejs 中body部分变成了:

1
2
3
4
5
6
7
8
<div class="container">
<div class="row">
<main id="main" class="col-md-9">
<%- body %>
</main>
<%- partial('_partial/sidebar',{item: page,table: true}) %>
</div>
</div>

然后在 after_footer.ejs 模板中加入 Pjax 相关代码进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script src="/js/jquery-2.2.4.min.js"></script>
<script src="/js/jquery.pjax.min.js"></script>
<!-- ... -->
<!-- 引入其他必要js脚本 -->

<script type="text/javascript">
$(document).ready(function(){
$(document).pjax('a[target!=_blank]', '#main', {fragment:'#main', timeout:8000}); // 绑定动态更新的节点

pageInit(); // 初始化页面内容的方法
});

$(document).on('pjax:send', function() {
NProgress.start(); // 进度条
});

$(document).on('pjax:complete', function() {
NProgress.done();
});

window.addEventListener('popstate', function(e) {
NProgress.done();
});

测试一下,初步运行成功了!

修复失效、报错的脚本

其实这步挺简单的,主要是个思路的问题。最佳方案是把所有零散的代码分类组合成方法,然后再看哪些方法是进网站加载一次就行的、哪些是需要跳转页面后再次加载的动态内容。

例如我的评论所使用的 Valine ,就需要在每次文章详情页中重新初始化。那就是定义好相关方法 commentInit,然后在合适的地方添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$(document).ready(function(){
$(document).pjax('a[target!=_blank]', '#main', {fragment:'#main', timeout:8000}); // 绑定动态更新的节点

pageInit(); // 初始化页面内容的方法
commentInit(); // 初始化评论
});

$(document).on('pjax:send', function() {
NProgress.start(); // 进度条
});

$(document).on('pjax:complete', function() {
NProgress.done();
commentInit(); // 初始化评论
});

window.addEventListener('popstate', function(e) {
NProgress.done();
commentInit(); // 初始化评论
});

那么这一步验证成功后,接下来就把相关的搜索功能依葫芦画瓢就行。当然,实际上很多js是不需要动态执行的,这个要按需规划。

加入网易云播放器

我这里什么插件都没有用到,直接在 footer.ejs 中增加网易云官方给出的 iframe 解决方案:

1
2
3
4
5
6
<!-- 网易云音乐插件 -->
<% if (theme.music && theme.music.enable){ %>
<div style="position:fixed; bottom:18px; right:60px; ">
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=110 src="<%=theme.music.src%>&auto=<%=theme.music.autoplay?1:0%>&height=90"></iframe>
</div>
<% } %>

<%=theme.music.src%> 这类常量当然是在 _config.yml 中配置好了。

测试一下,非常完美!

总结

有时候其实就差那么一点顿悟,上次折腾了好几天还没能解决的问题,这次多少是让人有点兴奋。赶紧把网站更新上来,有问题也好速速改掉。


♦ 本文固定连接:https://www.gsgundam.com/2023/12/2023-12-24-make-hexo-gacman-theme-compatible-with-pjax/

♦ 转载请注明:GSGundam 2023年12月24日发布于 GSGUNDAM砍柴工

♦ 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

♦ 原创不易,如果页面上有适合你的广告,不妨点击一下看看,支持作者。(广告来源:Google Adsense)

♦ 本文总阅读量