JavaScript History 對(duì)象

2023-03-20 15:45 更新

概述 

window.history屬性指向 History 對(duì)象,它表示當(dāng)前窗口的瀏覽歷史。

History 對(duì)象保存了當(dāng)前窗口訪問過的所有頁面網(wǎng)址。下面代碼表示當(dāng)前窗口一共訪問過3個(gè)網(wǎng)址。

window.history.length // 3

由于安全原因,瀏覽器不允許腳本讀取這些地址,但是允許在地址之間導(dǎo)航。

// 后退到前一個(gè)網(wǎng)址
history.back()

// 等同于
history.go(-1)

瀏覽器工具欄的“前進(jìn)”和“后退”按鈕,其實(shí)就是對(duì) History 對(duì)象進(jìn)行操作。

屬性 

History 對(duì)象主要有兩個(gè)屬性。

  • History.length:當(dāng)前窗口訪問過的網(wǎng)址數(shù)量(包括當(dāng)前網(wǎng)頁)
  • History.state:History 堆棧最上層的狀態(tài)值(詳見下文)
// 當(dāng)前窗口訪問過多少個(gè)網(wǎng)頁
window.history.length // 1

// History 對(duì)象的當(dāng)前狀態(tài)
// 通常是 undefined,即未設(shè)置
window.history.state // undefined

方法 

History.back()、History.forward()、History.go() 

這三個(gè)方法用于在歷史之中移動(dòng)。

  • History.back():移動(dòng)到上一個(gè)網(wǎng)址,等同于點(diǎn)擊瀏覽器的后退鍵。對(duì)于第一個(gè)訪問的網(wǎng)址,該方法無效果。
  • History.forward():移動(dòng)到下一個(gè)網(wǎng)址,等同于點(diǎn)擊瀏覽器的前進(jìn)鍵。對(duì)于最后一個(gè)訪問的網(wǎng)址,該方法無效果。
  • History.go():接受一個(gè)整數(shù)作為參數(shù),以當(dāng)前網(wǎng)址為基準(zhǔn),移動(dòng)到參數(shù)指定的網(wǎng)址,比如go(1)相當(dāng)于forward()go(-1)相當(dāng)于back()。如果參數(shù)超過實(shí)際存在的網(wǎng)址范圍,該方法無效果;如果不指定參數(shù),默認(rèn)參數(shù)為0,相當(dāng)于刷新當(dāng)前頁面。
history.back();
history.forward();
history.go(-2);

history.go(0)相當(dāng)于刷新當(dāng)前頁面。

history.go(0); // 刷新當(dāng)前頁面

注意,移動(dòng)到以前訪問過的頁面時(shí),頁面通常是從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁。

History.pushState() 

History.pushState()方法用于在歷史中添加一條記錄。

window.history.pushState(state, title, url)

該方法接受三個(gè)參數(shù),依次為:

  • state:一個(gè)與添加的記錄相關(guān)聯(lián)的狀態(tài)對(duì)象,主要用于popstate事件。該事件觸發(fā)時(shí),該對(duì)象會(huì)傳入回調(diào)函數(shù)。也就是說,瀏覽器會(huì)將這個(gè)對(duì)象序列化以后保留在本地,重新載入這個(gè)頁面的時(shí)候,可以拿到這個(gè)對(duì)象。如果不需要這個(gè)對(duì)象,此處可以填null
  • title:新頁面的標(biāo)題。但是,現(xiàn)在所有瀏覽器都忽視這個(gè)參數(shù),所以這里可以填空字符串。
  • url:新的網(wǎng)址,必須與當(dāng)前頁面處在同一個(gè)域。瀏覽器的地址欄將顯示這個(gè)網(wǎng)址。

假定當(dāng)前網(wǎng)址是example.com/1.html,使用pushState()方法在瀏覽記錄(History 對(duì)象)中添加一個(gè)新記錄。

var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');

添加新記錄后,瀏覽器地址欄立刻顯示example.com/2.html,但并不會(huì)跳轉(zhuǎn)到2.html,甚至也不會(huì)檢查2.html是否存在,它只是成為瀏覽歷史中的最新記錄。這時(shí),在地址欄輸入一個(gè)新的地址(比如訪問google.com),然后點(diǎn)擊了倒退按鈕,頁面的 URL 將顯示2.html;你再點(diǎn)擊一次倒退按鈕,URL 將顯示1.html。

總之,pushState()方法不會(huì)觸發(fā)頁面刷新,只是導(dǎo)致 History 對(duì)象發(fā)生變化,地址欄會(huì)有反應(yīng)。

使用該方法之后,就可以用History.state屬性讀出狀態(tài)對(duì)象。

var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
history.state // {foo: "bar"}

如果pushState的 URL 參數(shù)設(shè)置了一個(gè)新的錨點(diǎn)值(即hash),并不會(huì)觸發(fā)hashchange事件。反過來,如果 URL 的錨點(diǎn)值變了,則會(huì)在 History 對(duì)象創(chuàng)建一條瀏覽記錄。

如果pushState()方法設(shè)置了一個(gè)跨域網(wǎng)址,則會(huì)報(bào)錯(cuò)。

// 報(bào)錯(cuò)
// 當(dāng)前網(wǎng)址為 http://example.com
history.pushState(null, '', 'https://twitter.com/hello');

上面代碼中,pushState想要插入一個(gè)跨域的網(wǎng)址,導(dǎo)致報(bào)錯(cuò)。這樣設(shè)計(jì)的目的是,防止惡意代碼讓用戶以為他們是在另一個(gè)網(wǎng)站上,因?yàn)檫@個(gè)方法不會(huì)導(dǎo)致頁面跳轉(zhuǎn)。

History.replaceState() 

History.replaceState()方法用來修改 History 對(duì)象的當(dāng)前記錄,其他都與pushState()方法一模一樣。

假定當(dāng)前網(wǎng)頁是example.com/example.html。

history.pushState({page: 1}, 'title 1', '?page=1')
// URL 顯示為 http://example.com/example.html?page=1

history.pushState({page: 2}, 'title 2', '?page=2');
// URL 顯示為 http://example.com/example.html?page=2

history.replaceState({page: 3}, 'title 3', '?page=3');
// URL 顯示為 http://example.com/example.html?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

popstate 事件 

每當(dāng)同一個(gè)文檔的瀏覽歷史(即history對(duì)象)出現(xiàn)變化時(shí),就會(huì)觸發(fā)popstate事件。

注意,僅僅調(diào)用pushState()方法或replaceState()方法 ,并不會(huì)觸發(fā)該事件,只有用戶點(diǎn)擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用 JavaScript 調(diào)用History.back()、History.forward()、History.go()方法時(shí)才會(huì)觸發(fā)。另外,該事件只針對(duì)同一個(gè)文檔,如果瀏覽歷史的切換,導(dǎo)致加載不同的文檔,該事件也不會(huì)觸發(fā)。

使用的時(shí)候,可以為popstate事件指定回調(diào)函數(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));
});

回調(diào)函數(shù)的參數(shù)是一個(gè)event事件對(duì)象,它的state屬性指向pushStatereplaceState方法為當(dāng)前 URL 所提供的狀態(tài)對(duì)象(即這兩個(gè)方法的第一個(gè)參數(shù))。上面代碼中的event.state,就是通過pushStatereplaceState方法,為當(dāng)前 URL 綁定的state對(duì)象。

這個(gè)state對(duì)象也可以直接通過history對(duì)象讀取。

var currentState = history.state;

注意,頁面第一次加載的時(shí)候,瀏覽器不會(huì)觸發(fā)popstate事件。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)