github地址: pjax
中文说明文档(非官方): pjax


基本参数

$(document).pjax(selector, [container], options)
  1. selector为click选择器
  2. container为需要更新内容的容器选择器
  3. 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是一个对象,里面有一些选项可以自由配置,内容如下:

选项默认值说明
timeout650ajax 超时时间(单位 ms ),超时后会执行默认的页面跳转,所以超时时间不应过短,不过一般不需要设置
pushtrue使用 window.history.pushState 改变地址栏 url( 会添加新的历史记录 )
replacefalse使用 window.history.replaceState 改变地址栏 url( 不会添加历史记录 )
maxCacheLength20缓存的历史页面个数( pjax 加载新页面前会把原页面的内容缓存起来,缓存加载后其中的脚本会再次执行 )
version 返回当前pjax版本的字符串或者函数,本身没什么大用
scrollTo0页面加载后垂直滚动距离( 与原页面保持一致可使过度效果更平滑 )
type"GET"ajax 的参数,http 请求方式
dataType"html"ajax 的参数,响应内容的 Content-Type也就是数据类型
container 用于查找容器的 CSS 选择器,[container] 参数没有指定时使用
urllink.href要跳转的连接,默认 a 标签href 属性
targetlinkpjax 事件参数 eventrelatedTarget 属性,默认为点击的 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:clickpjax:clicked,其他所有pjax事件都是在pjax容器元素上触发的。

事件取消参数说明
pjax:click✔︎options点击按钮时触发。可调用 e.preventDefault(); 取消pjax
pjax:beforeSend✔︎xhr, optionsajax 执行 beforeSend 函数时触发,可在回调函数中设置额外的请求头参数。可调用 e.preventDefault(); 取消 pjax
pjax:start xhr, optionspjax 开始(与服务器连接建立后触发)
pjax:send xhr, optionspjax:start 之后触发
pjax:clicked options ajax 请求开始后触发
pjax:beforeReplace contents, optionsajax 请求成功,内容替换渲染前触发
pjax:success data, status, xhr, options内容替换成功后触发
pjax:timeout✔︎xhr, optionsoptions.timeout之后触发;除非被取消,否则会强制刷新页面,可调用 e.preventDefault(); 继续等待 ajax 请求结束
pjax:error✔︎xhr, textStatus, error, optionsajax 请求失败后触发。默认失败后会强制刷新页面,如要阻止可调用 e.preventDefault();
pjax:complete xhr, textStatus, optionsajax 请求结束后触发,不管成功还是失败
pjax:end xhr, optionspjax 所有事件结束后触发
pjax:popstate 页面导航方向: 'forward'/'back'(前进/后退)
pjax:start null, optionspjax 开始
pjax:beforeReplace contents, options内容替换渲染前触发,如果缓存了要导航页面的内容则使用缓存,否则使用 pjax 加载
pjax:end null, optionspjax 结束
pjax:callback null, options页面脚本加载完成后(Admui项目)

注意:

pjax:beforeReplace 事件前 pjax 会调用 extractContainer 函数处理页面内容,即以 script[src] 的形式引入的 js 脚本不会被重复加载,有必要可以改下源码

如果您使用了加载指示(如loading图标或“加载中”的文字),pjax:sendpjax: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 加载进度条

github

这是一款用于显示加载进度的顶部进度条,方法也很简单,就一个start和done方法就可以了,简单。

如果你是要改变样式颜色,自己去改源文件css或者自己再写一条css即可。

具体的方法看github文档即可,非常简单好用。

分类: 锋利的JQuery 标签: pjaxNProgress

评论

暂无评论数据

暂无评论数据

目录