什麼Ajax、Pjax、Njax。。。神馬玩意? 有Njax嗎? 木有。。。不過真有Pjax!!javascript
其實pjax就是用到了html5的新history api: pushState和replaceState。若是瀏覽器不支持,會自動降級爲普通http訪問,跟正常a連接同樣css
具體啥區別?先視覺通感感覺下!!上圖:html
一、普通的http切換頁面的請求方式,閃爍、白屏、卡頓、加載等,就是完整加載一坨頁面嘛,又慢又挫的,就像如花姑娘:html5
二、經過Ajax來開發頁面,只加在部分數據,沒有切換和閃爍,清新宜人哦,就像街上MM、鄰家小妹java
若是隻是ajax的話,不能保存頁面狀態!一刷新就沒了啊!!轉瞬即逝啊!!jquery
街上的MM都走遠了,童鞋別看了,找不到了!!git
若是要保存的話,結合hash#,其實很坑爹啊!es6
不少時候引入hash,致使開發複雜不說,關鍵是影響SEO,百度不認識 #! 啊 只有谷歌認識有毛線用啊被牆了!github
三、Pjax來了啊,喜大普奔!既能無切換、高性能加載顯示html,又能跟普通url兼容,先後端開發邏輯也簡單!web
就像下面的女神吉田沙世和攝影模特啊!關鍵是你還能抱回家,輕鬆hold住,各類調戲啊!臥槽。。說漏嘴了。。咳說正事!
說完了視覺上的通感感覺,咱們再看一眼開發的區別,是否是開發很麻煩啊 !!!上代碼:
MO.go('.ctn a', '#ttt')
而後呢?
木有了啊!只要後臺再根據請求頭區分下是不是pjax來返回片斷html代碼就能夠了!
瀏覽器不支持pjax怎麼辦? 自動將極爲普通http啊!!不用擔憂的!
艾瑪、這麼happy!真幸福!
簡直就是修煉玉女心經的節奏啊! 耶,操練起來!
- 首先須要jQuery這個基礎庫~其實能夠用純js寫這個pjax類庫的,可是,我懶。。。
- 引入編譯es5後到dist目錄下的 mo.pjax.es5.js 腳本文件到html文件,若是使用es6,請import並配置編譯
src="./dist/mo.pjax.es5.js"
能夠去github上下載: https://github.com/xunuoi/MO.Pjax
用法:
Api Params Desc 參數註釋:
_fetch : 是否請求網絡,好比此次pjax的url參數是/about ,若是_fetch爲false,那麼不發送http 請求或讀取緩存,只執行回調。
多用在複雜web/app設計中,好比當前內容已存在於html中,不想更新和獲取.
* MO.state默認值是false,由於只是從新定義本頁面狀態,不須要更新已有數據和HTML
* MO.touch中默認值是true,由於要從http或緩存中 更新數據、html
_fire:是否馬上觸發onpopfn ,馬上執行回調函數。false表示popstate 事件觸發後才執行
* MO.state中默認值是false, 只有popstate事件觸發後才執行
* MO.go中調用了MO.state,並傳參_fire值爲false.
* MO.define中調用了MO.state,並傳參_fire值爲true.
調教一下,再美的女神也不是天生就符合你的口味,來這定製下啊!
MO.config({ 'type': 'POST', // this can be used for you back-end ,to detect if it is a pjax request 'pjaxHeader': { 'X-Http-Pjax': 'Pjax' } })
詳細配置和註解:
{
'type': 'POST',// post is default http請求方式 // if cache data, 是否緩存 'cache': true, // 'cacheExpires': 10000, // 0 means always avaliable, default none 緩存時間 // if store data in localStorage , default true 'storage': true, //是否啓用localStorage //若是storageExpires設置爲0或false,永不過時 'storageExpires': 43200000, // 12 hours ,default 12 // the res data type, default html 'dataType': 'html', //返回數據類型,默認html // you can set your own header ,just use `pjaxHeader` opts, // which you can detect if it is an pjax request in back-end // 你能夠本身定義請求頭,方便後端判斷是不是pjax請求,若是是pjax, 返回部分html, fragment 'pjaxHeader': { 'Http-Request-Pjax': 'Fragment' }, // you can set the fn which will triggered before MO.touch and popstate event happened // 觸發pjax操做前和 出現popstate的事件時的事件函數, 參數是state,包含url、title等信息 before (state) { ... } //默認無 // you can set the beforeSend fn , before ajax request send. // jquery的ajax方法調用,請求前設置請求頭,能夠覆蓋 beforeSend (req){ let ph = this['pjaxHeader'] for (let h in ph ){ let v = ph[h] req.setRequestHeader(h, v) } } }
看看美女哪裏長得最漂亮啊
1、MO.go 最簡單!
MO.go(aSelector, ctnSelector, onSuccess)
這個是最簡單和經常使用的api, 只須要go一下,傳入2個參數便可,一個是點擊後觸發pjax的元素選擇器,通常是a,第二個是更新返回內容的html 。第三個是回調函數,可選。
MO.go添加處理錯誤的函數,好比出現網絡請求錯誤,好比404,會在此處捕獲
MO.go('.ctn a', '#ttt', function onSuccess(res, $aEle){ console.log(res, $aEle) }, function onError(err, $aEle){ console.log(err, $aEle) })
2、MO.define 不經常使用
定義當前頁面的state狀態,不經常使用
MO.define(ctn, htmlData)
3、MO.state 適合複雜開發
* MO.state和MO.go二者常常配合使用,比較靈活
詳細定義當前頁面state狀態,以及是否請求次url, 和是否馬上觸發onpopFn_fire
MO.state(url, title, onpopFn, _data=null, _fetch=false, _fire=false)
4、MO.go 複雜開發,很好用啊!!!
作複雜交互和邏輯時,比較經常使用
* 更強大和靈活的使用pjax, 能夠定義 pjax的操做的url、回調、是否發起此url的網絡請求等,一樣能夠添加fail的錯誤處理函數
MO.touch(apiUrl, title, onpopFn, _fetch=true)
給touch添加fail處理網絡請求錯誤,添加方式以下
MO.touch(apiUrl, title, onpopFn, _fetch=true) .fail(function(err) { console.log('There is an error ', err) })
服務端處理:
服務端只須要判斷是普通請求(完整html)仍是pjax請求(fragment html)
能夠經過MO.config({'pjaxHeader': {xxx: yyy}})來設置請求頭,或者修改type爲POST\GET等,只要讓服務端能判斷便可!
說明:
- 經過MO.touch和MO.state,能夠作很是複雜的pjax 應用,自定義事件\UI等
- 若是要簡單使用,就是直接 MO.go(), 傳入你想要pjax的a元素的selector便可
- 配合啓用cache/localStorage(默認都啓用), 給用戶更好操做體驗,減小等待、卡頓
本地存儲:store/removeStore
原來還有這麼個福利!!!
能夠在引入MO.Pjax的任何頁面,來store數據,當其餘頁面pjax到此頁面的時候,數據直接從storage獲取就能夠啦!這個在作多重請求方式的web開發時,常常用到哦!
- 提供本地存儲和自動過時機制,
- 過時時間經過MO.config({'storageExpires': xxx})來設定
- 自動建立一個item來跟蹤這條數據的時間: { k+'createdAt': (new Date).getTime() },
Store的Api
MO.store(k, v) MO.removeStore(k, v)
html代碼
<div class="ctn"> <h3>Test Mo.pjaxh3> <p> <a href="/about.html">Abouta> <a href="/toxic.html">Toxica> p> div> <div id="ttt" style="margin-top: 30px;"> <p>This is index htmlp> div> ------------------------------------------------------------------ <div>This is about htmldiv> ------------------------------------------------------------------ <div>This is toxic htmldiv>
JS 代碼
MO.go('.ctn a', '#ttt')
So easy! 搞定收工!
就似這麼簡單!就似這麼任性!
我娘不再用擔憂我無刷新更新頁面內容了!Pjax大法好!
趕忙把pjax女神抱回家!!!
http://karat.cc/article/5655bcdce6fecb6c65eded27