菜鸟站长
个人博客主题模板、应用插件、功能开发技术资源聚合分享网站

Typecho网站怎么使用MoOx/Pjax实现pjax

发布者:菜鸟站长  发布日期:2023-12-20  更新日期:2023-12-20  人气指数:170

这应该是Typecho上最简单的使用PJAX的方案了。

MoOx/Pjax 官方说明

轻松在任何网站上启用快速的AJAX 导航 (使用pushState() + XHR)

MoOx/Pjax(以下简称Pjax)是一个独立的JavaScript模块,使用AJAX(XmlHttpRequest)和pushState()来提供快速的浏览体验。

Pjax库方便你改善传统网站(服务端渲染的或者静态网站)的用户体验,使用户感觉像在使用应用程序,尤其是那些宽带质量差的用户。

不再需要完整的页面重新加载。不会创建多个HTTP请求。

Pjax不依赖于其他库,如jQuery或类似的库,完全使用原生JS编写。

初步改造

1.引入 JS(这里采用国内的CDN),建议修改footer.php引入,在</body>之前插入即可

<script>
document.addEventListener('pjax:send', () => {
NProgress.start();
});
document.addEventListener('pjax:complete', () => {
NProgress.done();
});
let pjax = new Pjax({
elements: 'a[href^="<?php $this->options->siteUrl(); ?>"]:not(a[target="_blank"], a[no-pjax], a[href^="<?php $this->options->adminUrl(); ?>"])',
selectors: [
"title",
".main-menu",
"main",
"#logout",
]
});
// 这里插入其他代码
</script>

注意这里要修改selectors,selectors是告诉脚本 Pjax 加载的新页面那些部分的内容要替换到网页上,格式为css选择器。比如title是网页标题;比如退出链接,我给加了个IDlogout,所以是#logout,如果 导航 菜单做了高亮当前也也是需要替换的,至于正文内容就更不用说了。

加载动画

加载动画是让用户有网页正在加载的感觉,推荐使用NProgress,或者你自己写也行。反正我用的是 Nprogress。
1.引入 Nprogress,放在 Pjax 脚本之前

<link href="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>

2.然后在 Pjax 初始化脚本之后插入

document.addEventListener('pjax:send', () => {
NProgress.start();
});
document.addEventListener('pjax:complete', () => {
NProgress.done();
});

pjax:sendpjax 刚开始发送网络请求时触发的事件
pjax:completepjax 完成后触发的事件
如果是使用 自定义 动画,请将NProgress.start()NProgress.done()替换为自己的代码

修复一些问题问题

1.开启了 Pjax 之后发现表情无法加载了,回到顶部不换用啦,Lazyload不加载 图片 啦,点赞弹窗不可用啦等等的问题都是因为Pjax只是替换部 分页 面内容,JS 那些还是原来老的,只能在PJAX完成的时候触发一下重载事件。

document.addEventListener('pjax:complete', () => {
NProgress.done();
new OwO(); // 重新初始化表情
GoTop.init(); // 货到顶部重载
LayzloadInstance.update() // Lazyload 重载
});

2.开启Pjax可以评论无法回复
我观察了一下,是因为 Typecho 默认输出的 评论 JS 是写死 comment-id 的,只能屏蔽原来的 JS 脚本,改成自动获取 ID的。
修改header.php$this->header()修改为$this->header('commentReply='),这样就可以屏蔽原来的输出。
Header 其他参数参见

自定义头部信息输出

屏蔽了评论 JS 输出就会导致无法评论,所以得增加修改版的评论JS,插入到 PJAX 初始化脚本后面即可

window.TypechoComment = {
dom: function (id) {
return document.getElementById(id);
},
query: function (sel) {
return document.querySelector(sel);
},
create: function (tag, attr) {
var el = document.createElement(tag);
for (var key in attr) {
el.setAttribute(key, attr[key]);
}
return el;
},
reply: function (cid, coid) {
var comment = this.dom(cid), parent = comment.parentNode,
response = this.query(".comment-respond"), input = this.dom('comment-parent'),
form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0],
textarea = response.getElementsByTagName('textarea')[0];
if (null == input) {
input = this.create('input', {
'type': 'hidden',
'name': 'parent',
'id': 'comment-parent'
});
form.appendChild(input);
}
input.setAttribute('value', coid);
if (null == this.dom('comment-form-place-holder')) {
var holder = this.create('div', {
'id': 'comment-form-place-holder'
});
response.parentNode.insertBefore(holder, response);
}
comment.appendChild(response);
this.dom('cancel-comment-reply-link').style.display = '';
if (null != textarea && 'text' == textarea.name) {
textarea.focus();
}
return false;
},
cancelReply: function () {
var response = this.query('.comment-respond')
holder = this.dom('comment-form-place-holder'), input = this.dom('comment-parent');
if (null != input) {
input.parentNode.removeChild(input);
}
if (null == holder) {
return true;
}
this.dom('cancel-comment-reply-link').style.display = 'none';
holder.parentNode.insertBefore(response, holder);
return false;
}
};

至此!享受你的pjax无刷新技术吧!

本文检索关键词:pjax

菜鸟站长推荐教程



添加新评论 »

icon_mrgreen.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_confused.pngicon_cool.pngicon_evil.pngicon_biggrin.pngicon_idea.pngicon_redface.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_surprised.pngicon_lol.pngicon_mad.pngicon_sad.pngicon_exclaim.pngicon_question.png