jquery-pjax学习记录

pjax是什么

pjax是jquery的一个插件,它使用ajax和pushState两个技术改善用户的网页浏览体验。具体来说,当用户使用a标签切换页面时,可以实现局部刷新的技术。

pjax主要做两方面的事儿:

  1. 用户点击链接发送ajax请求,服务器得到请求返回需要填充的HTML片段,客户端得到HTML片段然后插入更新区域
  2. 页面填充完毕后,使用pushState更新当前的URL

这个过程能实现页面局部刷新,比传统的页面切换刷新的体验好一些,因为:

  1. 只下载需要的HTML页面片段,没有JS、CSS解析
  2. 如果服务端配置了正确的pjax请求,则只返回要更新的HTML片段,客户端只更新必要的内容,避免了页面重新渲染的过程。

如何使用

1. 客户端

客户端设置分两步:

  1. 下载插件,包括jquery1.8+,或者npm安装,这部分参考文档,不赘述。
  2. 初始化pjax插件,并有条件的拦截a标签跳转。
初始化
$.fn.pjax

下面代码表示:当selector被点击时,执行ajax请求,并将返回的HTML字符串填充在container标记的位置。

$(document).pjax(selector, [container], options)

参数说明

  • selector:click事件的选择器
  • container:pjax容器id
  • options :配置参数

pjax options

key default description
timeout 650 ajax请求如果超时将触发强制刷新
push true 使用 [pushState][] 在浏览器中添加导航记录
replace false 是否使用replace方式改变URL
maxCacheLength 20 返回的HTML片段字符串最大缓存数
version 当前pjax版本
scrollTo 0 当页面导航切换时滚动到的位置. 如果想页面切换不做滚动重置处理,请传入false.
type "GET" 使用ajax的模板请求方法,参考 $.ajax
dataType "html" 模板请求时的type,参考 $.ajax
container 内容替换的CSS选择器
url link.href 用于ajax请求的url,可以是字符串或者返回字符串的函数
target link eventually the relatedTarget value for pjax events
fragment 从服务端返回的HTML字符串中子内容所在的CSS选择器,用于当服务端返回了整个HTML文档,但要求pjax局部刷新时使用。

可以使用下面的方式动态设置options:

$.pjax.defaults.timeout = 1200

初始化一般的做法是做好HTML结构,有条件的触发pjax跳转请求:

<div data-pjax>
    <a data-pjax href="/to/somewhere">ToSomewhere1</a>
    <a data-pjax href="/to/somewhere">ToSomewhere2/a>
</div>
<section id="pjax-container">
    <!-- 在这里更新返回的HTML字符串 -->
</section>
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')

2. 服务端

服务端也比较简单,监听HTTP的header中有X-PJAX的ajax请求,如果有则返回HTML片段,而不是整个HTML。

API介绍

这部分用于更细粒度的控制。

$.pjax.click

示例:

// 确定能使用pjax时
if ($.support.pjax) {
  $(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

用pjax提交表单

$(document).on('submit', 'form[data-pjax]', function(event) {
  $.pjax.submit(event, '#pjax-container')
})

$.pjax.reload

对当前URL使用pjax的方式重新获取HTML代码片段,并且在指定容器替换,这个过程不添加新的历史记录。(子片段重刷新)

$.pjax.reload('#pjax-container', options)

$.pjax

不是通过click触发pjax的时候使用。比如某些操作后自动触发pjax的过程。如果能获取到clickevent事件时,建议使用$.pjax-click(event)替换。

function applyFilters() {
  var url = urlForFilters()
  $.pjax({url: url, container: '#pjax-container'})
}

pjax生命周期

pjax生命周期简单的说:

点击pjax链接
触发浏览器前进后退

生命周期和Loading组件使用密切:

$(document).on('pjax:send', function() {
  $('#loading').show()
})
$(document).on('pjax:complete', function() {
  $('#loading').hide()
})

高级技巧

子页面加载完毕初始化其中的插件/组件

pjax只是请求HTML片段之后插入指定位置,因此片段内的JS插件/组件初始化需要在pjax:end事件后执行。

$(document).on('ready pjax:end', function(event) {
  $(event.target).initializeMyPlugin()
})

这段代码会在document ready或者container ready后执行initializeMyPlugin初始化方法(包括前进后退)。

强制reload

当使用pjax导致整个页面被强制刷时,可能的原因是:

  • 当返回的HTML片段包含<html>标签且fragment选择器没有指定时。如果指定了fragment选择器,pjax将从HTML文档中提取需要局部刷新的子片段。
  • 服务端返回的内容为空时。
  • HTTP响应的code是 4xx 或者 5xx。

浏览器重定向

在响应头中设置X-PJAX-URL,例如:

 request.headers['X-PJAX-URL'] = "http://example.com/hello"

Layout重新加载

当客户端页面的pjax版本和服务器返回的pjax版本不一致时,页面会重新刷新。

客户端页面的pjax版本:

<meta http-equiv="x-pjax-version" content="v123">

如果服务器修改了版本则重新刷新:

response.headers['X-PJAX-Version'] = "xxxx修改版本名称xxxx"

使用建议

这货需要服务端密切配合,如果服务端没设置好,要不就是请求只返回HTML片段,要不每次页面切换都是重新加载页面。

如果服务端无法完成这些配置,只能ajax异步由前端自己拼接HTML来做,建议使用MV*的库来做这部分。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,629评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,756评论 25 707
  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 3,179评论 0 7
  • 以前,没有互联网以前,人就已经在不断的协作,只是没有现在的高效。最滑稽的是,一个人只要做了什么坏事,只要换个地方,...
    行未阅读 244评论 2 1
  • //导航栏透明 [self.navigationController.navigationBar setBack...
    5斤8两阅读 259评论 0 1