nkovacs / jquery-pjax
pushState + ajax = pjax,由 Yii 框架核心开发者维护的分支
Requires
- bower-asset/jquery: >=1.8
This package is auto-updated.
Last update: 2024-08-25 03:42:11 UTC
README
.--.
/ \
## a a
( '._)
|'-- |
_.\___/_ ___pjax___
."\> \Y/|<'. '._.-'
/ \ \_\/ / '-' /
| --'\_/|/ | _/
|___.-' | |`'`
| | |
| / './
/__./` | |
\ | |
\ | |
; | |
/ | |
jgs |___\_.\_
`-"--'---'
简介
pjax 是一个 jQuery 插件,使用 ajax 和 pushState 提供具有真实永久链接、页面标题和可工作的后退按钮的快速浏览体验。
pjax 通过从您的服务器通过 ajax 获取 HTML 并用ajax获取的 HTML 替换页面容器的内容来工作。然后使用 pushState 更新浏览器当前 URL,而不会重新加载页面布局或任何资源(JS、CSS),给人一种快速、完整页面加载的错觉。但实际上只是 ajax 和 pushState。
对于不支持 pushState 的浏览器,pjax 会完全降级。
概述
pjax 不是完全自动的。您需要在您的页面上设置并指定一个包含元素,该元素在您导航网站时将被替换。
考虑以下页面。
<!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 监听 a
标签并使用 #pjax-container
作为目标容器来实现这一点
$(document).pjax('a', '#pjax-container')
现在当有人在兼容 pjax 的浏览器上点击“下一页”时,#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。
安装
Yii 2.0
由于它预装在 Yii 2.0 中,因此无需手动安装库。
bower
通过 Bower
$ bower install yii2-pjax
或者,将 yii2-pjax
添加到您的应用的 bower.json
文件中。
"dependencies": { "yii2-pjax": "latest" }
独立
pjax 可以直接下载到您的应用的公共目录中 - 只需确保您首先加载了 jQuery。
curl -LO https://raw.github.com/yiisoft/jquery-pjax/master/jquery.pjax.js
警告 不要直接链接原始脚本 URL。GitHub 不是一个 CDN。
依赖关系
需要 jQuery 1.8.x 或更高版本。
兼容性
pjax 只与支持 history.pushState API 的浏览器一起工作。当该 API 不受支持时,pjax 会进入降级模式:`$.fn.pjax` 调用将不会执行任何操作,`$.pjax` 将强制加载给定的 URL。
出于调试目的,即使浏览器支持 `pushState`,您也可以故意禁用 pjax。只需调用 `$.pjax.disable()`。要查看 pjax 是否实际支持 `pushState`,请检查 `$.support.pjax`。
用法
$.fn.pjax
让我们更详细地讨论最基本的上手方法。
$(document).pjax('a', '#pjax-container')
这将使所有链接启用pjax,并将容器指定为#pjax-container
。
如果您正在迁移现有网站,可能不想立即在所有地方启用pjax。而不是使用全局选择器如a
,尝试使用data-pjax
标记可pjax链接,然后使用'a[data-pjax]'
作为选择器。
或者尝试这个选择器,它会匹配<div data-pjax>
容器内的任何<a data-pjax href=>
链接。
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')
参数
$.fn.pjax
函数的概述是
$(document).pjax(selector, [container], options)
selector
是一个用于点击事件代理的字符串。container
是一个唯一标识pjax容器的字符串选择器。options
是一个具有以下键的对象。
pjax选项
您可以通过写入$.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:click
和pjax:clicked
之外的所有pjax事件都从pjax容器而不是被点击的链接中触发。
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
请求头,以区分pjax请求和常规XHR请求。在这种情况下,如果请求是pjax,我们跳过布局html,只渲染容器的内部内容。
强制重新加载的响应类型
默认情况下,如果pjax从服务器收到以下响应之一,它将强制整个页面重新加载
-
当没有明确配置
fragment
选择器时,页面内容包含<html>
。Pjax假设服务器的响应还没有为pjax正确配置。如果提供了fragment
pjax选项,pjax将简单地提取内容,根据该选择器将其插入DOM中。 -
空白页面内容。Pjax假设服务器无法提供适当的pjax内容。
-
HTTP响应码为4xx或5xx,表示某些服务器错误。
影响浏览器URL
如果服务器需要影响pjax导航后浏览器URL中显示的URL(例如,HTTP重定向与常规请求一样工作),它可以设置X-PJAX-URL
头。
def index request.headers['X-PJAX-URL'] = "http://example.com/hello" end
布局重新加载
在资源或html更改时,可以强制布局进行硬重新加载。
首先,使用自定义meta标签在您的标题中设置初始布局版本。
<meta http-equiv="x-pjax-version" content="v123">
然后,从服务器端设置X-PJAX-Version
头为相同的值。
if request.headers['X-PJAX'] response.headers['X-PJAX-Version'] = "v123" end
部署一个部署,将版本常量提升以强制客户端在下次请求时进行完全重新加载,获取新的布局和资源。