?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
概述
history.pushState(),history.replaceState()
history.state屬性
popstate事件
參考鏈接
瀏覽器窗口有一個history對象,用來保存瀏覽歷史。比如,該窗口先后訪問了三個地址,那么history對象就包括三項,length屬性等于3。
history.length // 3
history對象提供了一系列方法,允許在瀏覽歷史之間移動。
back():移動到上一個訪問頁面,等同于瀏覽器的后退鍵。
forward():移動到下一個訪問頁面,等同于瀏覽器的前進(jìn)鍵。
go():接受一個整數(shù)作為參數(shù),移動到該整數(shù)指定的頁面,比如go(1)相當(dāng)于forward(),go(-1)相當(dāng)于back()。
history.back(); history.forward(); history.go(-2);
如果移動的位置超出了訪問歷史的邊界,以上三個方法并不報錯,而是默默的失敗。
以下命令相當(dāng)于刷新當(dāng)前頁面。
history.go(0);
HTML5為history對象添加了兩個新方法,history.pushState() 和 history.replaceState(),用來在瀏覽歷史中添加和修改記錄。所有主流瀏覽器都支持該方法(包括IE10)。
if (!!(window.history && history.pushState)){ // 支持History API } else { // 不支持 }
上面代碼可以用來檢查,當(dāng)前瀏覽器是否支持History API。如果不支持的話,可以考慮使用Polyfill庫History.js。
history.pushState方法接受三個參數(shù),依次為:
state:一個與指定網(wǎng)址相關(guān)的狀態(tài)對象,popstate事件觸發(fā)時,該對象會傳入回調(diào)函數(shù)。如果不需要這個對象,此處可以填null。
title:新頁面的標(biāo)題,但是所有瀏覽器目前都忽略這個值,因此這里可以填null。
url:新的網(wǎng)址,必須與當(dāng)前頁面處在同一個域。瀏覽器的地址欄將顯示這個網(wǎng)址。
假定當(dāng)前網(wǎng)址是example.com/1.html
,我們使用pushState方法在瀏覽記錄(history對象)中添加一個新記錄。
var stateObj = { foo: "bar" }; history.pushState(stateObj, "page 2", "2.html");
添加上面這個新記錄后,瀏覽器地址欄立刻顯示example.com/2.html
,但并不會跳轉(zhuǎn)到2.html,甚至也不會檢查2.html是否存在,它只是成為瀏覽歷史中的最新記錄。假定這時你訪問了google.com,然后點(diǎn)擊了倒退按鈕,頁面的url將顯示2.html,但是內(nèi)容還是原來的1.html。你再點(diǎn)擊一次倒退按鈕,url將顯示1.html,內(nèi)容不變。
注意,pushState方法不會觸發(fā)頁面刷新。
如果 pushState 的url參數(shù),設(shè)置了一個當(dāng)前網(wǎng)頁的#號值(即hash),并不會觸發(fā)hashchange事件。如果設(shè)置了一個非同域的網(wǎng)址,則會報錯。
// 報錯 history.pushState(null, null, 'https://twitter.com/hello');
上面代碼中,pushState想要插入一個非同域的網(wǎng)址,導(dǎo)致報錯。這樣設(shè)計的目的是,防止惡意代碼讓用戶以為他們是在另一個網(wǎng)站上。
history.replaceState方法的參數(shù)與pushState方法一模一樣,區(qū)別是它修改瀏覽歷史中當(dāng)前頁面的值。假定當(dāng)前網(wǎng)頁是example.com/example.html。
history.pushState({page: 1}, "title 1", "?page=1"); history.pushState({page: 2}, "title 2", "?page=2"); history.replaceState({page: 3}, "title 3", "?page=3"); history.back(); // url顯示為http://example.com/example.html?page=1 history.back(); // url顯示為http://example.com/example.html history.go(2); // url顯示為http://example.com/example.html?page=3
history.state屬性保存當(dāng)前頁面的state對象。
history.pushState({page: 1}, "title 1", "?page=1"); history.state // { page: 1 }
每當(dāng)同一個文檔的瀏覽歷史(即history對象)出現(xiàn)變化時,就會觸發(fā)popstate事件。需要注意的是,僅僅調(diào)用pushState方法或replaceState方法 ,并不會觸發(fā)該事件,只有用戶點(diǎn)擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用JavaScript調(diào)用back、forward、go方法時才會觸發(fā)。另外,該事件只針對同一個文檔,如果瀏覽歷史的切換,導(dǎo)致加載不同的文檔,該事件也不會觸發(fā)。
使用的時候,可以為popstate事件指定回調(diào)函數(shù)。這個回調(diào)函數(shù)的參數(shù)是一個event事件對象,它的state屬性指向pushState和replaceState方法為當(dāng)前url所提供的狀態(tài)對象(即這兩個方法的第一個參數(shù))。
window.onpopstate = function(event) { console.log("location: " + document.location); console.log("state: " + JSON.stringify(event.state)); }; // 或者 window.addEventListener('popstate', function(event) { console.log("location: " + document.location); console.log("state: " + JSON.stringify(event.state)); });
上面代碼中的event.state,就是通過pushState和replaceState方法,為當(dāng)前url綁定的state對象。
這個state對象也可以直接通過history對象讀取。
var currentState = history.state;
另外,需要注意的是,當(dāng)頁面第一次加載的時候,在onload事件發(fā)生后,Chrome和Safari瀏覽器(Webkit核心)會觸發(fā)popstate事件,而Firefox和IE瀏覽器不會。
MOZILLA DEVELOPER NETWORK,Manipulating the browser history
MOZILLA DEVELOPER NETWORK,window.onpopstate
Louis Lazaris, HTML5 History API: A Syntax Primer