瀏覽器歷史就像一堆卡片,以下所示:html
在HTML4中,咱們已經可使用window.history對象來控制歷史記錄的跳轉,可使用的方法包括:git
方法 | 描述 |
---|---|
back() | 加載 history 列表中的前一個 URL。 |
forward() | 加載 history 列表中的下一個 URL。 |
go() | 加載 history 列表中的某個具體頁面。 |
HTML5引進了history.pushState()方法和history.replaceState()方法,它們容許你逐條地添加和修改歷史記錄條目。這些方法能夠協同window.onpopstate
事件一塊兒工做。github
方法 | 描述 |
---|---|
pushState() | 有三個參數:一個狀態對象、一個標題(如今會被忽略),一個可選的URL地址 |
replaceState() | 操做相似於history.pushState(),不一樣之處在於replaceState()方法會修改當前歷史記錄條目而並不是建立新的條目。 |
popstate事件 | 每當激活的歷史記錄發生變化時,都會觸發popstate事件。 |
若是要作瀏覽器兼容,能夠下載History.js解決。下面作個簡單的demo:ajax
<h1 id="number">1</h1> <a id="forward" href="?num=2">Go Forward</a>
var link = document.getElementById('forward'); var num = document.getElementById('number'); link.addEventListener('click', function(e){ e.preventDefault(); var myNum = parseInt(num.innerHTML, 10); num.innerHTML = ++myNum; history.pushState({count:myNum}, null, '?num='+myNum); document.title = 'Number'+myNum; });
點擊按鈕的時候,上面的URL在改變,但點擊瀏覽器的後退按鈕的時候,上面的內容是不變的。數組
接下來,咱們給popstate加個監聽器,監聽數字。數字內容也就會隨着改變了。瀏覽器
addEventListener('popstate', function(e){ if(e.state && e.state.count) { num.innerHTML = e.state.count; document.title = 'Number'+e.state.count; }else { num.innerHTML = 1; document.title = 1; } });
PAJX就是pushState+Ajax。同時使用這二者,只需更新頁面的一小部分和URL,頁面不須要從新加載,這樣就能極大加快訪問速度。緩存
創建一個單頁程序的方法不少,最簡單的就是使用一個路由。app
var routes = []; //創建route對象,插入到數組routes中 function addRoute(route, callback, scope) { var routeObj = { route: route, callback: callback, scope, scope }; routes.push(routeObj); } //匹配符合要求的route,並執行回調函數 function handleRoute(path, noHistory) { var len = routes.length, scope; for(var i=0; i<len; i++) { if(path.match(routes[i].route)) { //若是給定了做用域就用給的做用域 if(routes[i].scope) { scope = routes[i].scope; }else { scope = window; } //若是是來自popstate事件,就沒必要再加入到棧中 if(!noHistory) { history.pushState({}, null, path); } routes[i].callback.apply(scope, [path]); return true; } } //沒有route返回false return false; }
只需添加一個監聽器就能讓歷史記錄起做用。dom
window.addEventListener('popstate', function(e) { handleRoute(window.location.href, true); }); router = { handleRoute:handleRoute, addRoute:addRoute };
給頁面上的a標籤按鈕添加事件函數
//攔截單擊,簡單的綁定頁面上面的a標籤的點擊事件 document.addEventListener('click', function(e) { if(e.target.href) { if(router.handleRoute(e.target.href)) { e.preventDefault(); } } });
這裏還作了點簡單的緩存操做。點擊後退按鈕頁面上的內容還能存在。
//緩存ajax的響應 var pageCache = {}; //格式化連接 function normalizeLink(path) { return path.match(/([a-z_]+\.html)/)[1]; } //執行ajax請求或使用緩存 function handlePage(path) { var href = normalizeLink(path); if(pageCache[href]) { document.querySelector('.content').innerHTML = pageCache[href]; } else { ajax.makeRequest(href.replace('.html', '_frag.html'), function(xhr) { document.querySelector('.content').innerHTML = xhr.responseText; pageCache[href] = xhr.responseText; }, this); } } router.addRoute(/[a-z_]+\.html/, handlePage);
代碼是參照《HTML5觸摸界面設計與開發》這本書的示例demo而寫的。這本書的源碼能夠在這裏獲取到。
demo下載:
http://download.csdn.net/detail/loneleaf1/8730963
參考資料:
http://www.w3school.com.cn/jsref/dom_obj_history.asp History 對象
https://developer.mozilla.org/zh-CN/docs/DOM/Manipulating_the_browser_history 操縱瀏覽器的歷史記錄