Fluid主题下Pjax实现Aplayer音乐播放器全局不中断


千般荒凉,以此为梦。万里蹀躞,以此为! ——余秋雨《文化苦旅》

注:如果要在Fluid主题下实现Pjax,需要牺牲很多小功能,最后权衡再三还是关掉了

用Pjax实现Aplayer音乐播放器全局不中断的过程其实不太顺利,因为我用的主题没有像nexT一样内嵌Pjax功能,网上很多基于nexT的教程直接是npm个库然后在配置文件里enable:true一下就成功了,而我们用其他主题的选手需要从头配置到尾,其实从头配置倒不算难点,难的是因为主题的不同导致配置Pjax的时候出现的Bug也不同,需要自己一个个调试,而找不到参考资料这未知的Bug确实很让人抓狂,不过好在最后是解决了

接下来我将介绍在fluid主题下怎么配置Pjax实现Aplayer音乐播放器全局不中断,并附上各种踩坑的经历

1. 引入Pjax

先上Pjax文档

pjax = pushState + ajax
pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button.
pjax works by fetching HTML from your server via ajax and replacing the content of a container element on your page with the loaded HTML. It then updates the current URL in the browser using pushState. This results in faster page navigation for two reasons:
-No page resources (JS, CSS) get re-executed or re-applied;
-If the server is configured for pjax, it can render only partial page contents and thus avoid the potentially costly full layout render.

作者说:pjax = pushState + ajax ,即pjax是由可以 异步刷新页面的ajax弥补ajax导致url不变无法回退页面的pushState 组成的

和配置Aplayer一样,我依旧引用了镜像源的js文件(懒该打),将以下代码放在主题文件夹下layout/layout.ejs文件里</body>的前面:

1
2
3
4
5
6
7
8
9
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
<script>
// 对所有链接跳转事件绑定pjax容器pjax-container
$(document).pjax('a', '#pjax-container', {
fragment:'#pjax-container',
timeout:8000
});
</script>

踩坑点1:之前代码放在<header>标签里的时候,chrome的控制台总是报$(…).pjax is not a function,查找资料$(…).XXX is not a function的解决办法后把代码放在</body>前报错便成功消失

2. 使用Pjax

在主题文件夹下layout/layout.ejs文件里需要用pjax的地方套上id为pjax-container的div:

1
2
3
<div id="pjax-container">
...
</div>

在需要异步加载资源的部分套上<div id="pjax-container"></div>后整个pjax配置其实已经基本完成了,再往后就是各种不同主题的选手需要解决不同Bug的时间了

3. 踩坑记录

在以上步骤配置完后,我的全站页面跳转不中断音乐基本实现了,但零星有几个Bug需要解决:

Bug1:文章封面/内容里的图片 和 头像的图片 加载不出来

文章封面和内容里的图片以及头像的图片都加载不出来,我一开始以为是主题配置里的这部分资源不支持ajax请求,在pjax作者文档里$(document).pjax('a', '#pjax-container')的用法是这样写的:

The simplest and most common use of pjax looks like this:
$(document).pjax('a', '#pjax-container')
This will enable pjax on all links on the page and designate the container as #pjax-container.
If you are migrating an existing site, you probably don’t want to enable pjax everywhere just yet. Instead of using a global selector like a, try annotating pjaxable links with data-pjax, then use 'a[data-pjax]' as your selector. Or, try this selector that matches any <a data-pjax href=> links inside a <div data-pjax> container:
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')

即对于页面中所有id为pjax-container的a标签开启pjax,如果有些链接不想开启pjax,可以将函数改为$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container'),用带有data-pjax属性选择器的a标签代替全局a标签,并将想启用pjax的a标签加上data-pjax属性即这样:<a data-pjax href=>,然后还需将<a data-pjax href=>此标签嵌套在一个带有data-pjax属性的div标签即<div data-pjax> 里,这样的话不想用pjax的a标签不加data-pjax属性就行

网络上还有人写了另一种单独a标签不开启pjax的方法,详见使用 jQuery Pjax 做全站异步加载遇到的坑,他是将$(document).pjax('a', '#pjax-container')改为$(document).pjax('a[pjax!="exclude"]', '#pjax-container'),再在不开pjax的a标签内加上pjax="exclude"

当我尝试后发现…主题配置用的ejs模板引擎的写法我看不太懂,整个页面在哪引入图片资源这些具体的东西已经被抽象的七七八八了,然后我也不了解layout文件夹下所有ejs文件之间的关系(如果懂得话估计都是可以自己做主题出来的大佬了吧),然后在我不停将以上找到的方法在各个地方试过一遍无果后,差点就放弃配置pjax了。本来这篇文章就是想记录我当时配置pjax失败的经历,然后打算结尾写个“配置失败,在此记录只当作埋坑”(挽尊现场/逃/),但是吧…写的过程中突然又不甘心地跑去继续试

终于!我才发现…这些图片都是有懒加载的,遂跑去主题配置文件里把lazyload关掉了,然后终于成功实现全站pjax了!

而且因为开了pjax,文章第二次点击时,每篇文章的侧边栏导航和标题也消失了(啊…这难道就是鱼和熊掌不能兼得吗)

Bu2:因pjax失效的js

比如我之前引入的外部js如鼠标点击特效都是放在<header>标签里的,被pjax容器包裹住导致失效了,只需把引入的外部js移出pjax容器就行,比如将其放在<footer>标签里或者直接放在</body>结束标签前

如果是在异步刷新的页面里有不想要异步刷新的功能块,没办法分出来,那可以参考我Bug1里找到的方法,如作者文档里的$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container'),网上大佬的$(document).pjax('a[pjax!="exclude"]', '#pjax-container'),或者用一个处理js因pjax失效的函数:

1
2
3
4
5
<script>
//用一个回调函数处理因为pjax失效的js
$(document).on('pjax:complete', function() {
})
</script>

注:最后找到主题作者的Issues,发现作者也还没解决:
作者Issues回复
同时还有人发现有个大佬stalo 搞定了,结果这位大佬是用Typescript重写了Fluid主题的所有JS代码,好吧这不是我等菜鸟能搞定的,我觉得先躺平不用Pjax了…

The End


Fluid主题下Pjax实现Aplayer音乐播放器全局不中断
https://wwwhisperr.github.io/2022/07/14/demo04/
作者
Whisper
发布于
2022年7月14日
许可协议