jq pjax笔记
github地址: pjax
中文说明文档(非官方): pjax
基本参数
$(document).pjax(selector, [container], options)
- selector为click选择器
- container为需要更新内容的容器选择器
- options为设置
selector的一些技巧:
我们可以给a元素添加一个属性:data-pjax
来表示这是一个需要使用pjax的链接,这样就可以避免全部的a元素使用pjax了
<a href="xxxx" data-pjax>
$(document).pjax("a[data-pjax]", [container], options)
我们也可以给他的父元素比如是div的话,给div加上一个data-pjax
。
<div data-pjax>
<a href="xxxx">
</div>
$(document).pjax("[data-pjax] a", [container], options)
如果还想更精确一些,比如只能是站内链接:
// xxxxxx等于站内链接的前缀
$(document).pjax("[href='xxxxxx'] a", [container], options)
container容器选择器的一些注意事项:
如果是容器的话,我们可能要注意下有哪些内容是需要同步更新的,我们可以利用一个div元素去包裹这些内容,然后pjax每次获取到返回的数据时会将对应容器内的内容更新。
如果说第一个网页有这个容器,第二个网页没有,那么就会导致进入第二个网页后pjax效果失效了。
options设置选项:
options是一个对象,里面有一些选项可以自由配置,内容如下:
选项 | 默认值 | 说明 |
---|---|---|
timeout | 650 | ajax 超时时间(单位 ms ),超时后会执行默认的页面跳转,所以超时时间不应过短,不过一般不需要设置 |
push | true | 使用 window.history.pushState 改变地址栏 url ( 会添加新的历史记录 ) |
replace | false | 使用 window.history.replaceState 改变地址栏 url ( 不会添加历史记录 ) |
maxCacheLength | 20 | 缓存的历史页面个数( pjax 加载新页面前会把原页面的内容缓存起来,缓存加载后其中的脚本会再次执行 ) |
version | 返回当前pjax版本的字符串或者函数,本身没什么大用 | |
scrollTo | 0 | 页面加载后垂直滚动距离( 与原页面保持一致可使过度效果更平滑 ) |
type | "GET" | ajax 的参数,http 请求方式 |
dataType | "html" | ajax 的参数,响应内容的 Content-Type 也就是数据类型 |
container | 用于查找容器的 CSS 选择器 ,[container] 参数没有指定时使用 | |
url | link.href | 要跳转的连接,默认 a 标签 的 href 属性 |
target | link | pjax 事件参数 event 的 relatedTarget 属性,默认为点击的 a 标签 |
fragment | 使用响应内容的指定部分( CSS 选择器 )填充页面,服务端不进行处理导致全页面请求的时候需要使用该参数,简单的说就是对请求到的页面做截取 |
其中version 在设置中没什么用,因为他不是设置当前页面的版本号,如果你要设置当前页面的版本号,你需要使用meta标签
<meta http-equiv="x-pjax-version" content="v123">
content为版本号。
这个版本可以用于当两个页面它的布局不一样的时候,如果还是使用pjax来局部更新的话,就会导致布局错乱,这版本号的改变,作用就在这里,如果我们在xhr的response响应头信息里面,设置一个不一样的版本号,那么pjax就会判断,如果和当前页面不一样,整个页面强制刷新。
而设置头信息,因为我不是后端,不太清楚,这里就放一下官方的例子:
官方用的ruby
if request.headers['X-PJAX']
response.headers['X-PJAX-Version'] = "v123"
end
一般来说,能用到的属性就是container,fragment,timeout
这三个。
注意:
您可以在全局使用$.pjax.defaults
对象改变默认配置:
$.pjax.defaults.timeout = 1200
单独使用的pjax事件
$.pjax.click
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})
})
}
在这里,我们使用if($.support.pjax)
来判断浏览器是否支持pjax,然后在给document下的a元素绑定click事件,click触发一个函数,它会获取到a元素的第一个属性为data-pjax-container
的祖先元素,注意不是父元素,而是祖先元素,他会从内往外遍历。
获取到祖先元素后,我们拿到他的id并加上前缀#
,这就成为了一个id选择器了。
然后手动触发$.pjax.click
,将a元素的event对象传进去,并且第二个参数为一个对象,对象里面有一个key为container,它接受刚刚做的选择器。
然后一个自由控制的pjax诞生了。
$.pjax.submit
$(document).on('submit', 'form[data-pjax]', function(event) {
$.pjax.submit(event, '#pjax-container')
})
用法和click一样,这个一般用于表单的pjax,不知道是否合适博客的回复可见,回头可以试试效果。
$.pjax.reload
这是一个用于更新当前页面的方法,并且不会产生历史记录。
使用pjax机制发起一个当前URL的请求到服务器,并且通过响应的内容替换容器元素中的内容,同时不添加浏览器历史记录
$.pjax.reload('#pjax-container', options)
$.pjax
手动调用pjax。主要用于非click事件发起pjax请求的情况。如果可以获得click事件,请使用$.pjax.click(event)
来代替。
function applyFilters() {
var url = urlForFilters()
$.pjax({url: url, container: '#pjax-container'})
}
事件(生命周期)
除了pjax:click
和pjax:clicked
,其他所有pjax事件都是在pjax容器元素上触发的。
事件 | 取消 | 参数 | 说明 | |||
---|---|---|---|---|---|---|
pjax:click | ✔︎ | options | 点击按钮时触发。可调用 e.preventDefault(); 取消pjax | |||
pjax:beforeSend | ✔︎ | xhr, options | ajax 执行 beforeSend 函数时触发,可在回调函数中设置额外的请求头参数。可调用 e.preventDefault(); 取消 pjax | |||
pjax:start | xhr, options | pjax 开始(与服务器连接建立后触发) | ||||
pjax:send | xhr, options | pjax:start 之后触发 | ||||
pjax:clicked | options | ajax 请求开始后触发 | ||||
pjax:beforeReplace | contents, options | ajax 请求成功,内容替换渲染前触发 | ||||
pjax:success | data, status, xhr, options | 内容替换成功后触发 | ||||
pjax:timeout | ✔︎ | xhr, options | 在options.timeout 之后触发;除非被取消,否则会强制刷新页面,可调用 e.preventDefault(); 继续等待 ajax 请求结束 | |||
pjax:error | ✔︎ | xhr, textStatus, error, options | ajax 请求失败后触发。默认失败后会强制刷新页面,如要阻止可调用 e.preventDefault(); | |||
pjax:complete | xhr, textStatus, options | ajax 请求结束后触发,不管成功还是失败 | ||||
pjax:end | xhr, options | pjax 所有事件结束后触发 | ||||
pjax:popstate | 页面导航方向: 'forward'/'back'(前进/后退) | |||||
pjax:start | null, options | pjax 开始 | ||||
pjax:beforeReplace | contents, options | 内容替换渲染前触发,如果缓存了要导航页面的内容则使用缓存,否则使用 pjax 加载 | ||||
pjax:end | null, options | pjax 结束 | ||||
pjax:callback | null, options | 页面脚本加载完成后(Admui项目) |
注意:
pjax:beforeReplace
事件前 pjax 会调用 extractContainer
函数处理页面内容,即以 script[src]
的形式引入的 js
脚本不会被重复加载,有必要可以改下源码。
如果您使用了加载指示(如loading图标或“加载中”的文字),pjax:send
和pjax:complete
这两个事件会比较有用。它们只有在XHR请求(而不是从缓存中加载内容)时才会被触发:
$(document).on('pjax:send', function() {
$('#loading').show()
})
$(document).on('pjax:complete', function() {
$('#loading').hide()
})
以下是禁用 pjax:timeout
事件的示例。
$(document).on('pjax:timeout', function(event) {
// Prevent default timeout redirection behavior
event.preventDefault()
})
高级设置
重载或初始化插件
pjax的特点是它不会刷新页面即可获取并插入新内容。但是,如果其他jQuery插件(或库)为页面内容绑定了加载事件(如DOMContentLoaded),那么这些事件是无效的。 比较常用的一种做法是,在更新的页面内容范围内,重新初始化插件。
$(document).on('ready pjax:end', function(event) {
$(event.target).initializeMyPlugin()
})
initializeMyPlugin
是例子,它等于一个插件的初始化方法,它可以是任何插件的初始化方法。甚至还可以更复杂。
原理就是我们在页面ready加载完毕,或者pjax完毕后,触发该函数,在这个函数里面再初始化或者重新运行一些方法,这样就不会再jq更新完dom后,原有的一些事件失效。
根据网友分享,我们甚至可以将这些方法打包在一个js文件里面,然后每次都get请求一次这个js文件,js文件被请求完毕后会自动运行,这样就可以减少这这里书写的代码量。
强制重载的响应类型
默认情况下,如果pjax从服务器收到以下响应之一,则会强制重载页面:
- 页面包含
<html>
标签,没有明确指定fragment
选择器时。 pjax就会认为服务器端没有正确配置pjax响应。如果配置了fragment
选项,pjax将根据该选择器提取页面内容。 - 空白页面。pjax就会认为服务器端无法提供正确的pjax内容。
- HTTP状态码为4xx或5xx,表示某些服务器错误。
改变浏览器URL
如果服务器端需要改变浏览器地址栏中URL(如HTTP重定向),可以通过设置X-PJAX-URL
头来实现:
def index
request.headers['X-PJAX-URL'] = "http://example.com/hello"
end
重载布局
静态资源或页面发生变化时,布局可被强制进行重载
首先,用一个自定义的meta标签在页面head中初始化layout版本。
<meta http-equiv="x-pjax-version" content="v123">
然后,在服务器端设置相同的X-PJAX-Version
头。
if request.headers['X-PJAX']
response.headers['X-PJAX-Version'] = "v123"
end
部署后,版本不同时整个页面会强制重载,会重新发起请求来获取新的布局和相关资源。
这个就是通过版本号进行强制刷新。
这里再推荐一个加载进度条!
NProgress 加载进度条
这是一款用于显示加载进度的顶部进度条,方法也很简单,就一个start和done方法就可以了,简单。
如果你是要改变样式颜色,自己去改源文件css或者自己再写一条css即可。
具体的方法看github文档即可,非常简单好用。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据