pjax是jquery的一个插件,它使用ajax和pushState两个技术改善用户的网页浏览体验。
简单来说,它的作用就是可以在实现局部刷新的同时,记录浏览历史,能使用浏览器前进后退功能,浏览器的url也会跟随内容变化。
实现原理
用户点击链接时,pjax拦截了a标签的默认跳转动作,使用发送ajax请求,之后将服务器返回的HTML片段插入更新区域,页面填充完毕后,使用pushState更新当前的URL。
pushState
HTML5在History里增加了pushState方法,这个方法会将当前的url添加到历史记录中,然后修改当前url为新url。当然这个方法只会修改地址栏的Url显示,但并不会发出任何请求。
pushState的使用方法:1
history.pushState(state, title, url)
- state: 可以放任意你想放的数据,它将附加到新url上,作为该页面信息的一个补充。
- title: 页面标题,目前浏览器支持不好。
- url: 新url,也就是你要显示在地址栏上的url。
1 | history.replaceState(state, title, url) |
replaceState方法与pushState大同小异,区别只在于pushState会将当前url添加到历史记录,之后再修改url,而replaceState只是修改state和url,不添加历史记录。1
window.onpopstate
一般来说,每当url变动时&用户点击浏览器历史前进后退按钮 ,popstate事件都会被触发。但若是调用pushState来修改url,该事件则不会触发,因此,我们可以把它用作浏览器的前进后退事件。
生命周期
点击pjax链接
触发浏览器前进后退
根据pjax的生命周期,可以在不同时间触发需要的时间,官方提供的可绑定的event函数如下:
以添加loading为例,在pjax开始发送和完成之后执行,实现的代码如下:1
2
3
4
5
6$(document).on('pjax:send', function() {
$('#loading').show()
})
$(document).on('pjax:complete', function() {
$('#loading').hide()
})
配置使用
上文提到过,pjax通常使用链接或者按钮来触发,通过使用ajax请求得到html片段,首先来写一个demo来简单的应用pjax。
html1
2
3
4
5
6
7
8<div id="container">jQuery.pjax分页</div>
<ul class="pagination">
<li><a href="data.php?page=1">1</a></li>
<li><a href="data.php?page=2">2</a></li>
<li><a href="data.php?page=3">3</a></li>
<li><a href="data.php?page=4">4</a></li>
<li><a href="data.php?page=5">5</a></li>
</ul>
js1
$(document).pjax('a', '#container');
php1
2
3
$page = $_GET['page'];
echo $page;
这样就可以实现,在点击a链接时,内容区显示对应的页数,并且url会修改为对应的href。
因为使用了ajax,所以需要配置服务器打开
上面的demo中使用了pjax的简单应用,接下来介绍一下详细的配置项与使用1
$(document).pjax(selector, [container], options)
- selector 字符串,点击的对象选择器
- container 字符串,选择唯一标识pjax容器。
- options 下面所描述的一个对象。
举个栗子:1
2
3
4
5
6
7
8var pjaxoption = {
timeout: 10000,
container: '.main_content', /* 内容替换的容器 */
cache: false, /* 是否使用缓存 */
storage: false, /* 是否使用本地存储 */
titleSuffix: '' /* 标题后缀 */
};
$(document).pjax('a', '#content', pjaxoption)
在配置项初始完成后还可以进行修改:1
$.pjax.defaults.timeout = 1200
除此之外,pjax还有一些extend的方法来触发。1
2
3
4
5
6
7
8
9
10
11
12//$.pjax.click
$(document).on('click', 'a[data-pjax]', function(event) {
var container = $(this).closest('[data-pjax-container]')
var containerSelector = '#' + container.id
$.pjax.click(event, {container: containerSelector})
})
//$.pjax.submit
$(document).on('submit', 'form[data-pjax]', function(event) {
$.pjax.submit(event, '#pjax-container')
})
//$.pjax.reload
$.pjax.reload('#pjax-container', options)