jQuery.pjax.js 使用 AJAX 和 pushState 无刷新加载网页
pjax 是一个 jQuery 插件,使用 ajax 和 pushState 技术提供快速的浏览体验与真正的永久链接、网页标题、以及浏览器的后退前进按钮操作。
pjax 通过抓取 HTML 从您的服务器通过 Ajax 和更换容器页面上的 HTML 内容会与 Ajax。然后更新无需重新加载你的网页的布局或任何资源使用 pushstate 浏览器的当前 URL(JS、CSS),提供了一个快速的外观,全页面加载。但它确实就是 Ajax 和 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)
selector
是一个字符串,比如要点击的文本 event delegation.container
是一个字符串,选择唯一标识pjax容器。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:click
和 pjax: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: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()
})
服务器端
服务器配置将在语言和框架之间变化。下面的示例演示如何配置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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论