Typecho博客使用MoOx/Pjax实现pjax

Typecho博客使用MoOx/Pjax实现pjax

小菜狗
2023-06-10 / 1 评论 / 100 阅读 / 正在检测是否收录...

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 是网页标题;比如退出链接,我给加了个ID logout ,所以是 #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:send 是pjax刚开始发送网络请求时触发的事件
    pjax:complete 是pjax完成后触发的事件
    如果是使用自定义动画,请将 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=') ,这样就可以屏蔽原来的输出。

屏蔽了评论 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;
    }
};

0

打赏

评论 (1)

取消
  1. 头像
    ah
    Windows 7 · Google Chrome

    你这个joe魔改版怎么不加Pjax

    回复