說在前面
什么是PJAX呢? 站在應用角度的就是既實現了頁面無刷新的效果,同時也產生了瀏覽器的前進和后退,而且url也會變化。 也不是什么新鮮技術,主要是AJAX+html5 pushState和replaceState。 HTML5 為history提供了pushState和replaceState用來在瀏覽歷史記錄中添加和修改記錄。
PJAX是在群里看到朋友在聊,孤陋寡聞還沒聽過這個,平時也沒注意觀察。附圖Github實現了這個效果,當你切換標簽時頁面局部刷新,瀏覽URL也會變化。


AJAX載入與瀏覽器的前進和后退
眾所周知,Ajax可以實現頁面的無刷新操作——優點;但是,也會造成另外的問題,無法前進與后退!曾幾何時,Gmail似乎借助iframe搞定,如今,HTML5讓事情變得如同過家家般簡單。
當執行Ajax操作的時候,往瀏覽器history中塞入一個地址(使用pushState)(這是無刷新的);於是,返回的時候,通過URL或其他傳參,我們就可以還原到Ajax之前的模樣。
實例分析
參考張鑫旭的Demo我自己試了一把。
<a href="/Home/Region?area=pudong">浦東</a>|<a href="/Home/Region?area=baoshan">寶山</a>|<a href="/Home/Region?area=jiading">嘉定</a>
<ul id="result">
</ul>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
$(function () {
var eleMenus = $('a').bind('click', function (event) {
var query = this.href.split('?')[1];
if (history.pushState && query) {
$('#result').empty();
$.ajax({
url: this.href,
type: 'get',
dataType: 'json',
success: function (data) {
$.each(data, function (i, v) {
$('<li>' + v.name + ',' + v.price + ',' + v.address + '' + '</li>').appendTo('#result');
});
}
});
var title = $(this).text();
if (event && /\d/.test(event.button)) {
history.pushState({ title: title }, title, location.href.split
('?')[0] + '?' + query);
}
}
return false;
});
var fnHashTrigger = function (target) {
var query = location.href.split("?")[1], eleTarget = target || null;
if (typeof query == "undefined") {
if (eleTarget = eleMenus.get(0)) {
// 如果沒有查詢字符,則使用第一個導航元素的查詢字符內容
history.replaceState(null, document.title, location.href.split("#")[0] + "?" + eleTarget.href.split("?")[1]) + location.hash;
fnHashTrigger(eleTarget);
}
} else {
eleMenus.each(function () {
if (eleTarget === null && this.href.split("?")[1] === query) {
eleTarget = this;
}
});
if (!eleTarget) {
// 如果查詢序列沒有對應的導航菜單,去除查詢然后執行回調
history.replaceState(null, document.title, location.href.split("?")[0]);
fnHashTrigger();
} else {
$(eleTarget).trigger("click");
}
}
}
if (history.pushState) {
window.addEventListener('popstate', function () {
fnHashTrigger();
});
}
fnHashTrigger();
});
</script>
實現效果



思路
- 每次手動點擊左側的菜單,我將Ajax地址的查詢內容(
?后面的)附在demo HTML頁面地址后面,使用history.pushState塞到瀏覽器歷史中。 - 瀏覽器的前進與后退,會觸發
window.onpopstate事件,通過綁定popstate事件,就可以根據當前URL地址中的查詢內容讓對應的菜單執行Ajax載入,實現Ajax的前進與后退效果。 - 頁面首次載入的時候,如果沒有查詢地址、或查詢地址不匹配,則使用第一個菜單的Ajax地址的查詢內容,並使用
history.replaceState更改當前的瀏覽器歷史,然后觸發Ajax操作
參考
http://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/
http://www.cnblogs.com/hustskyking/p/history-api-in-html5.html
