前言
因为上次更新后加入了音乐插件,但是有个问题就是在页面跳转的时候由于页面已经刷新了,所以音乐就不会继续播放了,就想着去引入Pjax
来解决这个问题,同时引入pjax
后比较直观的改变就是整个网站变成单页应用,在一定程度上会提高用户体验且已经加载过的表态资源不会再重复加载,站点的响应速度会有进一步的改善
什么是Pjax?
pushState + ajax = pjax,利用 HTML5
的 pushState()
和 replaceState()
新特性和 ajax
结合实现。pushState()
和 replaceState()
用来操作 State(状态)对象,即可添加和修改历史记录,进而更新 url 和提供前进、后退操作 ajax 实现数据的异步加载进而局部刷新,下面是官方的介绍
Pjax可以利用github上面的一个开源项目defunkt/jquery-pjax来快速帮我们实现
使用
js文件引入
前提是引入jquery,然后引入jquery-pjax,我这里是通过CDN的方式去引入,大家也可以下载下来后上传到自己的cdn或网站上
<!-- jquery -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<!-- jquery-pjax -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
调用方式
我们先来看看调用方式
$(document).pjax(selector, [container], options)
参数说明
参数名 | 说明 |
---|---|
selector | 给哪些selector绑定pjax事件,一般的为a标签 , 如果要去掉一些外连的URL, 这里的selector可以为a[href^="你的URL"] |
container | 内容变换容器的selector,是指哪个容器里的内容发生的变换,如: '#app-main',在页面跳转时只刷新这个部分 |
options | 传入一个对象,常用属性如下: |
options.container | 内容变换容器的selector |
options.timeout | 超时就会被迫页面就会完全刷新,单位毫秒 |
options.fragment | 这个作为整个pjax框架,必须写上 |
例如在freewind主题中是这么使用的
$(document).pjax(
'a[href^="<?php Helper::options()->siteUrl()?>"]:not(a[target="_blank"],a[no-pjax]), a[href^="?"]',
{
container: '#app-main',
fragment: '#app-main',
timeout: 8000
}
)
解释
<?php Helper::options()->siteUrl()?>
是typecho的自带函数,调用本站的首页地址,就是说本站地址开头且属性不包含target="_blank"
和no-pjax
或 以?
开头的a标签
都会进行pjax刷新,以?
开头是有些地方传参时可能直接省略的站点url
#app-main
是局部刷新的容器的selector,大家根据自己的主题自行修改
加载动画
pjax为我们提供了两个回调事件
pjax:send:pjax加载之前
pjax:complete:pjax加载成功之后
所以我们可以在pjax加载之前开启动画,加载成功之后结束动画,我这里用的是nprogress这个进度条动画
所以我们的代码就成了如下
$(document).pjax(
'a[href^="<?php Helper::options()->siteUrl()?>"]:not(a[target="_blank"],a[no-pjax]), a[href^="?"]',
{
container: '#app-main',
fragment: '#app-main',
timeout: 8000
}
).on('pjax:send', function () {
NProgress.start();//加载动画效果开始
}).on('pjax:complete', function () {
NProgress.done();//加载动画效果结束
});
js插件不生效
pjax采用的是异步请求资源,也就是每次请求数据不是重新获取整个页面的数据而是只会获取#pjax-container
容器里面的数据。所以如果js
脚本在容器外的话就不会被加载执行了,所以我们可以定义一个reload
函数在pjax结束时进行回调,以freewind
主题为例,最终代码如下:
function reload() {
// 初始化freewind题
window.freewind = new Freewind($("#is-page").data('page').trim() === 'page')
if (window.freewind.page) {
//如果是文章详情面
window.freewind.registerPage()
}
//自定义挂载点,部分插件可能需要初始化,可以写在这里
<?php Typecho_Plugin::factory('freewind')->pjaxload(); ?>
window.freewind.topInit()
window.freewind.registerHandler()
}
//第一次进行页面进行初始化
reload();
$(document).pjax(
'a[href^="<?php Helper::options()->siteUrl()?>"]:not(a[target="_blank"],a[no-pjax]), a[href^="?"]',
{
container: '#app-main',
fragment: '#app-main',
timeout: 8000
}
).on('pjax:send', function () {
NProgress.start();//加载动画效果开始
}).on('pjax:complete', function () {
reload();//pjax加载结束完重新初始化
NProgress.done();//加载动画效果结束
});
结束
至此,typecho
开启pjax结束,大家还不快去试试,有什么不懂的地方可以在下方评论,我看到后会帮大家解答
梦泽 游客 2023-11-25 14:12 回复
还是看不懂
叫啥名好 游客 2022-07-09 04:11 回复
成功了,美滋滋,谢谢博主
小 游客 2022-04-05 15:36 回复
谢辞. 游客 2022-03-22 13:58 回复
是篇水文无疑了
常瑞 游客 2021-12-27 21:00 回复
学费了
MR丶冷文 管理员 2021-12-27 21:01 回复
@常瑞
啊 pjax改起来还是很简单的,毕竟别人已经封装好了