什么是PJAX

pjax = pushState + ajax

pjax是一个Query插件,它通过ajax和pushState技术提供了极速的(无刷新ajax加载)浏览体验,并且保持了真实的地址、网页标题,浏览器的后退(前进)按钮也可以正常使用。

pjax的工作原理是通过ajax从服务器端获取HTML,在页面中用获取到的HTML替换指定容器元素中的内容。然后使用pushState技术更新浏览器地址栏中的当前地址。以下两点原因决定了pjax会有更快的浏览体验:

  1. 不存在页面资源(js/css)的重复加载和应用;
  2. 如果服务器端配置了pjax,它可以只渲染页面局部内容,从而避免服务器渲染完整布局的额外开销

安装PJAX

引入jQuery

WordPress有内置的jQuery版本,在header.php文件中的</head>之前添加以下代码即可引用

<?php wp_enqueue_script("jquery"); ?>

引入PJAX

这里使用js引入的方法,在functions.php文件中添加以下代码:

function add_pjax() {
    wp_register_script( 'pjax' , 'https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js' );
    wp_enqueue_script( 'pjax' );
add_action( 'wp_enqueue_scripts' , 'add_pjax' );

当然你也可以吧jquery.pjax.min.js文件下载到本地然后引入

使用PJAX

PJAX方法概述

$(document).pjax(selector, [container], options)
  • selector:string类型,用于click事件委托 的选择器。
  • container:string类型,用于标识唯一pjax容器的选择器。
  • options:object类型,这里列出部分选项。
    • timeout:ajax超时时间(毫秒),超时后强制刷新整个页面
    • push true:使用 pushState 在浏览器中添加历史记录
    • container:被替换内容元素的CSS选择器
    • fragment:css选择器,提取ajax响应内容中指定的内容片段

全站PJAX

先附上一个最简单的版本

jQuery(document).ready(function($) {
$(document).pjax('a[target!=_blank][pjax!="no"]', '#main-container', {fragment:'#main-container', timeout:6000});
});

添加加载动画

pjax项目还提供了一些pjax事件。以便在pjax执行前后加载一些东西。
加载动画只需要使用这两个事件pjax:sendpjax:complete

比如添加一个淡入淡出的动画

jQuery(document).ready(function($) {
$(document).pjax('a[target!=_blank][pjax!="no"]', '#main-container', {fragment:'#main-container', timeout:6000});
    $(document).on('pjax:send', function() {
        $('#main-container').fadeTo(700,0.0);
    });
    $(document).on('pjax:complete', function() {
        $('#main-container').fadeTo(700,1);
    });
});

或者自己写一个加载动画,在加载时显现出来。

jQuery(document).ready(function($) {
$(document).pjax('a[target!=_blank][pjax!="no"]', '#main-container', {fragment:'#main-container', timeout:6000});
    $(document).on('pjax:send', function() {
        $("#loading").css('display','block');
    });
    $(document).on('pjax:complete', function() {
        $("#loading").css('display','none');
    });
});

关于js失效的问题

pjax采用的是异步请求资源,也就是每次请求数据不是重新获取整个页面的数据而是只会获取#main-container容器里面的数据。所以如果一个函数在容器外面,在A页面没有,B又需要的话,那么从A页面进入B页面,这个函数就不会执行。必须回调这个函数。
比如我使用的fancybox以及lazy load,就需要在pjax:complete事件里重载相关函数即可。

$(document).on('pjax:complete', function() {
    $("#loading").css('display','none'); 
    jQuery('[data-fancybox="gallery"]').fancybox();
    jQuery(function() {
        jQuery(".post-gallery img, div.lazy").lazyload({effect: "fadeIn"});
}