jquery-pjax學習記錄

pjax是什么

pjax是jquery的一個插件,它使用ajax和pushState兩個技術改善用戶的網頁瀏覽體驗。具體來說,當用戶使用a標簽切換頁面時,可以實現局部刷新的技術。

pjax主要做兩方面的事兒:

  1. 用戶點擊鏈接發送ajax請求,服務器得到請求返回需要填充的HTML片段,客戶端得到HTML片段然后插入更新區域
  2. 頁面填充完畢后,使用pushState更新當前的URL

這個過程能實現頁面局部刷新,比傳統的頁面切換刷新的體驗好一些,因為:

  1. 只下載需要的HTML頁面片段,沒有JS、CSS解析
  2. 如果服務端配置了正確的pjax請求,則只返回要更新的HTML片段,客戶端只更新必要的內容,避免了頁面重新渲染的過程。

如何使用

1. 客戶端

客戶端設置分兩步:

  1. 下載插件,包括jquery1.8+,或者npm安裝,這部分參考文檔,不贅述。
  2. 初始化pjax插件,并有條件的攔截a標簽跳轉。
初始化
$.fn.pjax

下面代碼表示:當selector被點擊時,執行ajax請求,并將返回的HTML字符串填充在container標記的位置。

$(document).pjax(selector, [container], options)

參數說明

  • selector:click事件的選擇器
  • container:pjax容器id
  • options :配置參數

pjax options

key default description
timeout 650 ajax請求如果超時將觸發強制刷新
push true 使用 [pushState][] 在瀏覽器中添加導航記錄
replace false 是否使用replace方式改變URL
maxCacheLength 20 返回的HTML片段字符串最大緩存數
version 當前pjax版本
scrollTo 0 當頁面導航切換時滾動到的位置. 如果想頁面切換不做滾動重置處理,請傳入false.
type "GET" 使用ajax的模板請求方法,參考 $.ajax
dataType "html" 模板請求時的type,參考 $.ajax
container 內容替換的CSS選擇器
url link.href 用于ajax請求的url,可以是字符串或者返回字符串的函數
target link eventually the relatedTarget value for pjax events
fragment 從服務端返回的HTML字符串中子內容所在的CSS選擇器,用于當服務端返回了整個HTML文檔,但要求pjax局部刷新時使用。

可以使用下面的方式動態設置options:

$.pjax.defaults.timeout = 1200

初始化一般的做法是做好HTML結構,有條件的觸發pjax跳轉請求:

<div data-pjax>
    <a data-pjax href="/to/somewhere">ToSomewhere1</a>
    <a data-pjax href="/to/somewhere">ToSomewhere2/a>
</div>
<section id="pjax-container">
    <!-- 在這里更新返回的HTML字符串 -->
</section>
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')

2. 服務端

服務端也比較簡單,監聽HTTP的header中有X-PJAX的ajax請求,如果有則返回HTML片段,而不是整個HTML。

API介紹

這部分用于更細粒度的控制。

$.pjax.click

示例:

// 確定能使用pjax時
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})
  })
}

$.pjax.submit

用pjax提交表單

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

$.pjax.reload

對當前URL使用pjax的方式重新獲取HTML代碼片段,并且在指定容器替換,這個過程不添加新的歷史記錄。(子片段重刷新)

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

$.pjax

不是通過click觸發pjax的時候使用。比如某些操作后自動觸發pjax的過程。如果能獲取到clickevent事件時,建議使用$.pjax-click(event)替換。

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

pjax生命周期

pjax生命周期簡單的說:

點擊pjax鏈接
觸發瀏覽器前進后退

生命周期和Loading組件使用密切:

$(document).on('pjax:send', function() {
  $('#loading').show()
})
$(document).on('pjax:complete', function() {
  $('#loading').hide()
})

高級技巧

子頁面加載完畢初始化其中的插件/組件

pjax只是請求HTML片段之后插入指定位置,因此片段內的JS插件/組件初始化需要在pjax:end事件后執行。

$(document).on('ready pjax:end', function(event) {
  $(event.target).initializeMyPlugin()
})

這段代碼會在document ready或者container ready后執行initializeMyPlugin初始化方法(包括前進后退)。

強制reload

當使用pjax導致整個頁面被強制刷時,可能的原因是:

  • 當返回的HTML片段包含<html>標簽且fragment選擇器沒有指定時。如果指定了fragment選擇器,pjax將從HTML文檔中提取需要局部刷新的子片段。
  • 服務端返回的內容為空時。
  • HTTP響應的code是 4xx 或者 5xx。

瀏覽器重定向

在響應頭中設置X-PJAX-URL,例如:

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

Layout重新加載

當客戶端頁面的pjax版本和服務器返回的pjax版本不一致時,頁面會重新刷新。

客戶端頁面的pjax版本:

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

如果服務器修改了版本則重新刷新:

response.headers['X-PJAX-Version'] = "xxxx修改版本名稱xxxx"

使用建議

這貨需要服務端密切配合,如果服務端沒設置好,要不就是請求只返回HTML片段,要不每次頁面切換都是重新加載頁面。

如果服務端無法完成這些配置,只能ajax異步由前端自己拼接HTML來做,建議使用MV*的庫來做這部分。

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,886評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,124評論 25 708
  • AJAX 原生js操作ajax 1.創建XMLHttpRequest對象 var xhr = new XMLHtt...
    碧玉含香閱讀 3,265評論 0 7
  • 以前,沒有互聯網以前,人就已經在不斷的協作,只是沒有現在的高效。最滑稽的是,一個人只要做了什么壞事,只要換個地方,...
    行未閱讀 256評論 2 1
  • //導航欄透明 [self.navigationController.navigationBar setBack...
    5斤8兩閱讀 271評論 0 1