阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      插件 jQuery-pjax 中文API文档

      插件 jQuery-pjax 中文API文档

      源码 & 下载

      pjax是一个jQuery插件,它通过ajax和pushState技术提供了极速的(无刷新ajax加载)浏览体验,并且保持了真实的地址、网页标题,浏览器的后退(前进)按钮也可以正常使用。

      pjax的工作原理是通过ajax从服务器端获取HTML,在页面中用获取到的HTML替换指定容器元素中的内容。然后使用pushState技术更新浏览器地址栏中的当前地址。以下两点原因决定了pjax会有更快的浏览体验:

      • 不存在页面资源(js/css)的重复加载和应用;
      • 如果服务器端配置了pjax,它可以只渲染页面局部内容,从而避免服务器渲染完整布局的额外开销。

      项目现状

      jquery-pjax的维护方向:可能会继续修复重要的bug,但其功能不会再发生变化,即不会再实现新功能,也不会再扩展现有功能。

      安装

      pjax依赖于jQuery 1.8或者更高版本。

      通过npm安装

      npm install jquery-pjax
      

      通过js引入

      下载 jquery.pjax.js 插件并在页面中引用:

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

      方法

      $.fn.pjax

      最简单常见的pjax使用方法如下:

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

      通过这种方式可以让页面中所有的链接都实现pjax加载,并指定#pjax-container作为容器元素。

      如果您正在迁移已有网站,可能不希望在每个地方都使用pjax。那么您可以用data-pjax来注明这是一个pjax链接,然后使用a[data-pjax]来代替全局选择器a。或者,您也可以使用在<div data-pjax>容器中的<a data-pjax href="...">链接作为选择器。

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

      服务器端配置

      理论上,您在服务器端可通过检查指定的X-PJAXHTTP头来识别pjax请求,并且只渲染指定的HTML内容,这也就意味着在浏览器端我们不用重新渲染整个页面,只替换指定容器元素(在我们的示例中是 #pjax-container)中的内容即可。下面的示例是在Ruby on Rails中的实现方法:

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

      如果您想了解比上述方案更为自动化的方案,请查看 Turbolinks 。

      看一下您喜欢的服务器端框架是否有对应的 pjax插件 。

      也可以查看 RailsCasts #294: Playing with PJAX .

      参数

      $.fn.pjax 方法概述:

      $(document).pjax(selector, [container], options)
      
      • selector:string类型,用于click 事件委托 的选择器。
      • container:string类型,用于标识唯一pjax容器的选择器。
      • options object类型,包含下列选项。

      pjax配置选项

      选项默认值说明
      timeout650ajax超时时间(毫秒),超时后强制刷新整个页面
      pushtrue使用 pushState 在浏览器中添加历史记录
      replacefalse替换URL地址但不添加浏览器历史记录
      maxCacheLength20容器元素缓存内容的最大值(次)
      versionstring或function,返回当前pjax版本
      scrollTo0浏览器滚动条的垂直滚动位置。设为false时禁止滚动
      type“GET”参考 $.ajax
      dataType“html”参考 $.ajax
      container被替换内容元素的CSS选择器
      urllink.hrefstring或function,返回ajax请求响应的URL
      targetlinkpjax 事件 中relatedTarget属性的最终值
      fragmentcss选择器,提取ajax响应内容中指定的内容片段

      您可以在全局使用$.pjax.defaults对象改变默认配置:

      $.pjax.defaults.timeout = 1200
      

      $.pjax.click

      这是一个$.fn.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})
        })
      }
      

      注意 通过$.support.pjax我们明确浏览器是支持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。主要用于非click事件发起pjax请求的情况。如果可以获得click事件,请使用$.pjax.click(event)来代替。

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

      事件

      除了pjax:clickpjax:clicked,其他所有pjax事件都是在pjax容器元素上触发的。

      事件取消参数说明
      pjax链接事件的生命周期
      pjax:click✔︎options链接被激活的时候触发;取消的时候阻止pjax
      pjax:beforeSend✔︎xhr, options可以设置XHR头
      pjax:startxhr, options
      pjax:sendxhr, options
      pjax:clickedoptionspjax通过链接点击已经开始之后触发
      pjax:beforeReplacecontents, options从服务器端加载的HTML内容完成之后,替换当前内容之前
      pjax:successdata, status, xhr, options从服务器端加载的HTML内容替换当前内容之后
      pjax:timeout✔︎xhr, options在options.timeout之后触发;除非被取消,否则会强制刷新页面
      pjax:error✔︎xhr, textStatus, error, optionsajax请求出错;除非被取消,否则会强制刷新页面
      pjax:completexhr, textStatus, options无论结果如何,都在ajax响应完成后触发
      pjax:endxhr, options
      浏览器前进后退事件的生命周期
      pjax:popstatedirection事件的属性: “back”/“forward”
      pjax:startnull, options内容替换之前
      pjax:beforeReplacecontents, options在用缓存中的内容替换HTML之前
      pjax:endnull, options替换内容之后
      pjax:callbacknull, options页面脚本加载完成后(Admui项目)

      注意 由于Admui项目对本插件做了一些修改,建议不要使用官方原版插件替换。

      如果您使用了加载指示(如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()
      })
      

      该方法可以让$.fn.initializeMyPlugin()在页面普通加载和pjax加载时(点击链接或浏览器前进后退按钮之后)都能被调用。

      强制重载的响应类型

      默认情况下,如果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
      

      部署后,版本不同时整个页面会强制重载,会重新发起请求来获取新的布局和相关资源。

      目录
      目录