typecho博客实现pjax

介绍

官方介绍:pushState + ajax = pjax 带来最直观的效果是整个网站变成单页应用。这样的效果将会极大的提升用户体验,并且可以减少https的请求的次数和内容。使用github上面的一个开源项目defunkt/jquery-pjax 可以很轻松的帮助我们实现pjax。

!> 需要具备基础的html & javascript 知识。如果你连divscript标签仍然不认识,请忽略该篇文章。

一、实现

js文件引入

1.引入jquery.min.js

<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>

放在footer.php里就好。或者放在header.php都行!(不使用cdn提供的地址也可以,可以使用自己空间上传的js地址,下同)

2.引入jquery.pjax.js

<script src="//cdn.bootcss.com/jquery.pjax/1.9.6/jquery.pjax.min.js"></script>

同样的,放在header.php或者footer.php都行。 但一定要放在jquery.min.js的后面
(或者自己下载这个项目里的jshttps://github.com/defunkt/jquery-pjax这个项目里面下载里面的jquery.pjax.js

如何使用

footer.php里面加上这段代码就初步成功。【继续往下看!尤其是container的介绍】

<script>
$(document).pjax(selector, [container], options) 
</script>
  • selector 给哪些selector绑定pjax事件,一般的为:"a", 如果要去掉一些外连的URL, 这里的selector可以为: "a[href^='http://www.ihewro.com']"
  • [container] 内容变换容器,是指哪个容器里的内容发生的变换,如: '#pjax-content'。就是页面中只刷新的这个部分。
  • options 官方文档提供了更多的选项,以便更好地自定义选项。具体查考官方文档。以下列出我使用的一些选项。

    • container 替换的容器的css选择器。填你的替换容器ID即可。
    • timeout 超时就会被迫页面就会完全刷新,单位毫秒。
    • fragment 这个作为整个pjax框架,必须写上。

所以,代码可以这样写

<script>
$(document).pjax('a[href^="<?php Helper::options()->siteUrl()?>"]:not(a[target="_blank"], a[no-pjax])', {
    container: '#pjax-container',
    fragment: '#pjax-container',
    timeout: 8000
})
</script>

一定要放在jquery.min.jsjquery.pjax.min.js 的后面

解释一下上面代码:<?php Helper::options()->siteUrl()?>是typecho的自带函数,调用本站的首页地址!也就是只对本站的,并且没有_blank属性的,标签里不含no-pjax的链接实行pjax!局部刷新的区域#pjax-container的部分!

其中#pjax-container是你的局部刷新部分,你可能没有这个div,你自己在添加一个<div id="pjax-container"></div>包裹住你想局部刷新的部分就行了!

二、加载动画

pjax项目还提供了一些pjax事件。以便在pjax执行前后加载一些东西。

加载动画只需要使用这两个事件pjax:sendpjax:complete

如我之前写的:

<script>
$(document).on('pjax:send',
function() {
    $('#loader-wrapper').addClass("in");
})

$(document).on('pjax:complete',
function() {
    $('#loader-wrapper').removeClass("in");
})
</script>
解释一下上面代码:就是在pjax执行开始的时候,给#loader-wrapper加上in的样式名称。在pjax结束的时候给给#loader-wrapper去掉in的样式名称,这样就有了加载出现动画,加载后动画消失的效果。

我目前主题"Leaf"使用的加载动画来自这儿:nprogress:http://ricostacruz.com/nprogress/

nprogress使用起来更简单。在pjax:send的事件里面添加:NProgress.start(); .在pjax:complete的事件里面添加:NProgress.done();
更多使用方法点开链接,看一下github的说明就行!

三、一些问题的解决

pjax采用的是异步请求资源,也就是每次请求数据不是重新获取整个页面的数据而是只会获取#pjax-container容器里面的数据。所以如果一个函数在容器外面(如多说加载函数),在A页面没有,B又需要的话,那么从A页面进入B页面,这个函数就不会执行。必须回调这个函数。

注: 不同主题对于#pjax-container选取不一样以及结构可能不同解决方法会有不同(一般是差不多的)

多说

pjax:complete事件里面加上这段代码

if ($('.ds-thread').length > 0) { if (typeof DUOSHUO !== 'undefined') DUOSHUO.EmbedThread('.ds-thread'); else $.getScript("https://www.ihewro.com/duoshuo/embedhw4.min.js"); }
})

其他的js失效问题

pjax:complete事件 重载相关函数即可。

举例
<script>
$(document).on('pjax:complete',
function() {
    GenerateContentList();
    setupContents();
    rebindEvents();
if ($('.ds-thread').length > 0) { if (typeof DUOSHUO !== 'undefined') DUOSHUO.EmbedThread('.ds-thread'); else $.getScript("https://www.ihewro.com/duoshuo/embedhw4.min.js"); }
})
</script>

所以,最后我的pjax代码就是酱紫的!

<script>
//pjax 刷新

$(document).pjax('a[href^="<?php Helper::options()->siteUrl()?>"]:not(a[target="_blank"], a[no-pjax])', {
    container: '#pjax-container',
    fragment: '#pjax-container',
    timeout: 8000
}).on('pjax:send',
function() {
    NProgress.start();//加载动画效果开始
    
}).on('pjax:complete',
function() {
NProgress.done();//加载动画效果结束
imageeffct();//灯箱函数重载
 setupContents();//某个函数重载
lue();//lue函数重载
reHighlightCodeBlock();//代码高亮函数重载

if ($('.ds-thread').length > 0) { if (typeof DUOSHUO !== 'undefined') DUOSHUO.EmbedThread('.ds-thread'); else $.getScript("https://www.ihewro.com/duoshuo/embedhw4.min.js"); }
});//多说模块重载

</script>

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

最后修改:2019 年 02 月 26 日 12 : 23 PM
如果觉得我的文章对你有用,请随意赞赏

44 条评论

  1. 小九

    谢谢分享|´・ω・)ノ

  2. Ojhdt

    求教一波博主|´・ω・)ノ
    我已经在标签前引入了 Pjax,并在前添加了适合自己的代码,局部刷新部分也已经成功配置。
    但很遗憾,Pjax并没有生效。请问要如何处理哇。
    另外希望求得联系方式

    1. 友人C
      @Ojhdt
      其中#pjax-container是你的局部刷新部分,你可能没有这个div,你自己在添加一个<div id="pjax-container"></div>包裹住你想局部刷新的部分就行了!

      主要是你的页面中要有这个div

      1. Ojhdt
        @友人C

        另外,请问Pjax能同时对两处局部刷新区域进行处理吗?

  3. 季悠然

    博主请教一下!
    fancybox的重载函数要怎么写呢

    1. 季悠然
      @季悠然

      突然明白了,不用麻烦博主啦

  4. 图南山

    pjax 1.9.6版本应配合jq2..版本使用,否则无法正常工作。如果要使用jq3..版本,应使用pjax2.0.1以上版本。望博主标注一下。

  5. byg

    大佬好, 请勿我用了pjax之后原来的lazyload 的图片和 recaptcha 都不能显示了, 有什么解决方法吗

    1. 友人C
      @byg

      在回调函数里面添加对应的启动函数

  6. Rinvay

    大佬,我用您的方法开启typecho的pjax结果一直报错!我也在适当位置加入了div,还是报错!Uncaught the container selector '#pjax-container' did not match anything每一次点击首页就会Uncaught ReferenceError: NProgress is not defined

    1. 友人C
      @Rinvay

      因为你没引入NProgress 第三方动画库,就在complete 和 send 删除NProgress相关代码即可

      1. Rinvay
        @友人C

        博主您好,这一点我知道了,我其实还想请教您另一个关于instantclick的,东西,就是他如何兼容OwO.min.js

        1. Ratdis
          @Rinvay

          我也遇到了这个问题QAQ
          Uncaught ReferenceError: OwO is not defined
          得刷新才正常
          请教下您咋解决的,感谢

  7. 老陈

    默认模板,捣鼓了一下午还是不行

  8. 九四

    加载动画部分中的代码倒数第二行的反括号用错了

  9. 路途

    测试一下

  10. Hodpel

    哇我记得以前搞这个就是到处乱搞搞了好久才弄出样子的...早知道来这里看看

  11. 人性玩偶

    为什么我使用pjax后, 首页点击最新评论的锚记链接时,只会进入内容页面,不会跳到评论那里,需要在点一次才可以。

  12. 夏目贵志

    pjax 内容刷新 标题不刷新 怎么回事!

  13. 夏目贵志

    还是博主的清晰易懂!

  14. 后宫学长

    很好的教程……
    支持一个!
    也MARK一个、|´・ω・)ノ

  15. mo

    谢谢分享~

发表评论