大家在浏覽Facebook的相冊時有沒有發現,頁面局部重新整理的同時位址欄的位址也改變了,而且不是hash的方式。它使用的就是HTML5 history新增的幾個API,作為window的一個全局變量,在HTML4的時代history已不是什麼新鮮的事物了。我們經常使用的就有history.back()以及history.go() 。
下面我們來了解下history都有哪些改變。
1. HTML4時代的history API
A) history.length:目前曆史清單中的曆史記錄數(我大概測了下,IE6+是從0開始的,其他的是從1開始的,若有誤請回報哈,^_^);
B) history.go(n):前進或後退n條記錄,當n=0或空時會重新整理目前頁;
C) history.back():後退一步;
D) history.forward():前進一步;
2. HTML5新增的API
A) history.pushState(data, title [, url]):往曆史記錄堆棧頂部添加一條記錄;data會在onpopstate事件觸發時作為參數傳遞過去;title為頁面标題,目前所有浏覽器都會忽略此參數;url為頁面位址,可選,預設為目前頁位址;
B) history.replaceState(data, title [, url]) :更改目前的曆史記錄,參數同上;
C) history.state:用于存儲以上方法的data資料,不同浏覽器的讀寫權限不一樣;
D) window.onpopstate:響應pushState或replaceState的調用;
有了這幾個新的API,針對支援的浏覽器,我們可以建構使用者體驗更好的應用了。就像剛提到的Facebook相冊,雖然是AJAX的方式,但使用者可以直接複制頁面位址分享給好友,好友打開看到的就是AJAX加載的資料,做到了書簽化。當然這裡面需要做的工作遠不是說的這麼簡單。
3. 浏覽器的相容性&檢測
在HTML5支援不一的時代,新的API總會存在或這或那的相容性問題。是以我們有必要了解新接口在不同浏覽器下的相容性。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnauQEOlATOlUTRlQkQlETOlUTRlEUQlMUOlYTRl8CX5AzLcFTMwIzLcNHZh9GbwV3LcRnblRnbvNWLwd3Lc12bj5SehBnblRnLklGdvw1LcpDc0RHaiojIsJye.jpg)
截圖來自:《Manipulating the browser history》
如何檢測浏覽器是否支援History API?
function supports_history_api() {
return !!(window.history && history.pushState);
}
如何檢測history.state的相容性呢?我嘗試指派history.state=1,但history.state在不同浏覽器下的讀寫權限不一樣,是以我們換種方式:
var originalHistoryState = history.state; // 儲存原有的曆史資訊
history.replaceState(1, null); // 替換目前曆史資訊
var stateSupport = history.state == 1; // 是否存儲到剛設定的曆史資訊
history.replaceState(originalHistoryState, null); // 恢複原來的曆史資訊
4. 安全性
我們看一個例子:DEMO頁面在tenpay.com的域名下,使用者點選“付款”連結嘗試加載另一個域名的某張圖檔。
可以看到,當我們嘗試改變目前位址為一個協定不同、(子)域名不同的位址時,會觸發相應的錯誤。新API在安全性方面作了考慮,是以還是安全的。
5. AJAX Bookmark – AJAX書簽化
有了新API的支援,我們可以針對不同浏覽器作一些差異化的使用者體驗。尤其是在AJAX盛行的年代,無曆史記錄已經是一大诟病。
為了解決AJAX的書簽化問題,我們需要解決的主要是以下2個問題:
1. 浏覽器對新的HTML5 History API的支援不一;
2. 不支援的浏覽器我們如何解決前進/後退的問題 ;
對于問題1,我們采用的是hash方案,這也是很多方案采用的辦法了;主要原理這裡不細說了,大家可以搜尋一下。
下面是我寫的解決方案;大家可以參考下,歡迎互相探讨。
github位址:https://github.com/zawaliang/History
6. 一些參考文檔
- W3C html5 history:http://www.w3.org/TR/html5/history.html
- Introducing the HTML5 History API:http://dev.opera.com/articles/view/introducing-the-html5-history-api/
- Manipulating the browser history:https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
- Detecting HTML5 Features:http://diveintohtml5.org/detect.html
- window.history:https://developer.mozilla.org/en/DOM/window.history
- window.onpopstate:https://developer.mozilla.org/en/DOM/window.onpopstate
- MooTools onhashchange:http://yearofmoo.com/onhashchange/