jQuery.pjax.js 使用 AJAX 和 pushState 无刷新加载网页

发布于 2018-07-16 字数 13338 浏览 1176 评论 0

pjax 是一个 jQuery 插件,使用 ajax 和 pushState 技术提供快速的浏览体验与真正的永久链接、网页标题、以及浏览器的后退前进按钮操作。

pjax 通过抓取 HTML 从您的服务器通过 Ajax 和更换容器页面上的 HTML 内容会与 Ajax。然后更新无需重新加载你的网页的布局或任何资源使用 pushstate 浏览器的当前 URL(JS、CSS),提供了一个快速的外观,全页面加载。但它确实就是 Ajax 和 pushstate。

点击这里查看 pushState 的浏览器支持情况

概述

pjax 不是全自动的。您需要设置和指定一个包含在您的页面上的元素,当您浏览您的网站时将被替换。

可以参考下面的 HTML 代码结构和标签:

<!DOCTYPE html>
<html>
<head>
  <!-- styles, scripts, etc -->
</head>
<body>
  <h1>My Site</h1>
  <div class="container" id="pjax-container">
    Go to <a href="/page/2">next page</a>.
  </div>
</body>
</html>

我们要 pjax 抓取 URL  /page/2  然后替换 #pjax-container 不管它什么回来。没有风格或脚本将被加载,甚至 <h1> 可以保持不变 – 我们只是想改变 #pjax-container 元素。

我们会告诉pjax监听一个标签和使用 #pjax-container 作为目标容器:

$(document).pjax('a', '#pjax-container')

现在在pjax兼容浏览器,点击 “next page” 网页的内容容器 #pjax-container 中的内容将被 /page/2 内容替换。

魔法!差不多你还需要配置你的服务器来寻找pjax请求并发送回pjax具体内容。

pjax 的 ajax 请求会发送一个 X-PJAX 文件头,因此,在这个例子中(在大多数情况下)我们希望将页面的内容返回,而不需要任何与该头文件的任何请求的布局。

这是它可能看起来像在 Rails 上:

def index
  if request.headers['X-PJAX']
    render :layout => false
  end
end

如果你想要更多的自动解决方案比pjax钢轨检查 Turbolinks.

也可以点击这里 RailsCasts #294: Playing with PJAX.

安装插件

通过bower安装

$ bower install jquery-pjax

或者,添加 jquery-pjax 到你的 bower.json 文件中。

"dependencies": {
   "jquery-pjax": "latest"
}

standalone

pjax可以直接下载到你的应用程序的公共目录,请确保在此之前你已经加载jQuery。

curl -LO https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js

注意:不要盗链原始脚本的URL,Github不是一个CDN。

依赖关系

需要 jQuery 1.8.x 或者更高版本。

兼容性

pjax 只能工作在高级版本的浏览器中,点击这里查看浏览器对 history.pushState API 的兼容情况。 当API不支持pjax进入备用模式: $.fn.pjax 的调用将无法运行,并且 $.pjax 将硬盘加载给定的网址。

用于调试目的,你可以故意甚至浏览器是否支持禁用pjax pushState。只需要调用 $.pjax.disable()。看看pjax实际上是支持 pushState,调用 $.support.pjax

使用方法

$.fn.pjax

让我们以最基本的方式来谈一谈如何使用jQuery.pjax.js:

$(document).pjax('a', '#pjax-container')

这将使所有的链接pjax和指定的容器例如: #pjax-container.

如果你把一个现存的网站,你可能不想让pjax无处不在。而不是使用一个全球性的选择像A的注释与pjaxable链接 data-pjax,使用 'a[data-pjax]' 到你的选择器中。

或者试试这个选择器匹配任何 <a data-pjax href=> 链接插入 <div data-pjax> 容器。

$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')

参数

内容提要 $.fn.pjax 函数是:

$(document).pjax(selector, [container], options)
  1. selector 是一个字符串,比如要点击的文本 event delegation.
  2. container 是一个字符串,选择唯一标识pjax容器。
  3. options 下面所描述的一个对象。
pjax 可选参数
参数 默认值 描述
timeout 650 Ajax超时毫秒之后完全刷新是被迫的
push true 使用 pushState 在导航中添加浏览器历史记录
replace false 更换网址不添加浏览器历史记录
maxCacheLength 20 大缓存大小为以前的容器内容
version 一个字符串或函数返回当前pjax版
scrollTo 0 垂直位置以滚动导航。为了避免改变滚动位置,通过设置为 false.
type "GET" 网页请求的方式,详见 $.ajax
dataType "html" 返回的数据类型,详见 $.ajax
container CSS选择器的元素,其中的内容应及时更换
url link.href 字符串或函数返回的URL ajax请求
target link 最终 relatedTarget 的值,通过 pjax events
fragment CSS选择器的碎片从Ajax响应提取

您可以通过写全局更改默认设置 $.pjax.defaults 对象:

$.pjax.defaults.timeout = 1200

$.pjax.click

这是由$.fn.pjax本身较低水平的功能。它可以让你获得更多的控制在pjax事件处理。

本例使用当前点击上下文来设置一个父级作为容器:

if ($.support.pjax) {
  $(document).on('click', 'a[data-pjax]', function(event) {
    var container = $(this).closest('[data-pjax-container]')
    $.pjax.click(event, {container: container})
  })
}

注意:使用隐形的 $.support.pjax 保证,我们没有使用 $.fn.pjax 因此,我们应该避免结合此事件处理程序,除非浏览器实际上是要使用pjax。

$.pjax.submit

通过pjax提交表单。

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

$.pjax.reload

启动一个应用pjax机制服务器当前的URL请求和响应替换容器。不添加浏览器历史条目。

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

$.pjax

手动调用pjax。主要用于当你想在一个处理程序,并不是来自于点击开始pjax请求。如果你可以得到一个点击 event,容器 $.pjax.click(event) 代替。

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

事件方法

所有pjax事件除了 pjax:clickpjax:clicked 从pjax容器,不被点击的链接被解雇。

事件 取消 参数 注意
在下面的一个pjaxed链接事件生命周期
pjax:click ✔︎ options 阻止一个链接的默认事件,防止阻止pjax事件
pjax:beforeSend ✔︎ xhr, options 参见 XHR headers
pjax:start xhr, options
pjax:send xhr, options
pjax:clicked options pjax后,已经得到了从点击一个链接开始
pjax:beforeReplace contents, options 在内容被替换前,HTML从服务器加载的内容
pjax:success data, status, xhr, options 在内容被替换后,HTML 内容从服务器加载
pjax:timeout ✔︎ xhr, options 在选项 options.timeout;之后除非取消,否则将很难刷新
pjax:error ✔︎ xhr, textStatus, error, options 一个ajax错误,将执行原始的网页刷新,直到网页加载被取消
pjax:complete xhr, textStatus, options 总是在pjax执行完成以后调用,不论运行的结果
pjax:end xhr, options
浏览器的后退/前进导航事件生命周期
pjax:popstate 事件 direction 属性:”back”/”forward”
pjax:start null, options 更换内容前
pjax:beforeReplace contents, options 就在从缓存替换HTML内容
pjax:end null, options 更换内容后

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()
})

服务器端

服务器配置将在语言和框架之间变化。下面的示例演示如何配置Rails。

def index
  if request.headers['X-PJAX']
    render :layout => false
  end
end

一个 X-PJAX 请求头文件 header 设置为区分正常XHR请求一个pjax请求。在这种情况下,如果请求是pjax,我们跳过布局HTML只是使容器内的内容。

点击这里选择一个合适的 pjax plugin 为您最喜爱的服务器框架。

迫使重新加载响应类型

默认情况下,pjax 将迫使页的全部重新加载,如果它接收到来自服务器下列反应之一:

  • 网页内容引入 <html>fragment 选择没有明确的配置。Pjax假定服务器的响应没有被正确配置为pjax。假如 fragment pjax选项,则pjax只会解压缩到插入基于该选择器的DOM的内容。
  • 页面内容是空白的。Pjax assumes that the server is unable to deliver proper pjax contents.
  • HTTP服务器返回 4xx 或 5xx代码,说明一些服务器错误。

影响浏览器的网址

如果服务器需要影响,这将出现在pjax导航后浏览器的URL的URL(如HTTP重定向工作正常请求),它可以查看 X-PJAX-URL 头文件:

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

布局重新加载

布局可以被强迫做硬重装时,资产或HTML的变化。

首先设置你的头在初始布局版采用了自定义的元标记。

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

然后从服务器端,设置 X-PJAX-Version 头文件为下面的样子:

if request.headers['X-PJAX']
  response.headers['X-PJAX-Version'] = "v123"
end

部署一个部署,将该版本常数凸到迫使客户机做一个完整的重新加载下一个请求获得新的布局和资产。

相关链接

如果你对这篇文章有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助。

扫码二维码加入Web技术交流群

您暂时不能评论!

管理员开启了需要登录才能够评论,你可以免费注册一个本站的账号。

还没有评论!

目前还没有任何评论,快来抢沙发吧!