- 深入理解React Router:從原理到實踐
- 李楊韜
- 1174字
- 2021-04-16 16:10:42
2.3.2 history導航
1.history.push
history.push類似于1.2.1節中的history.pushState,會添加新的歷史棧記錄。其調用語法為:

其接收字符形式的路徑,也接收location地址描述對象。
hashHistory使用瀏覽器地址的hash部分作為路由存儲,每次hashHistory.push調用僅改變瀏覽器地址的hash值,這在某些不支持HTML5特性的舊式瀏覽器中可被使用。hashHistory.push的底層history源碼為:

調用window.location.hash進行一次hash改變,從而實現改變瀏覽器地址hash并入棧的操作。


注意,對于location,history.push調用是按照整個瀏覽器協議進行的,如可調用history.push('/foo/baz#121')。這會在瀏覽器中產生兩個#號,第一個#號后為hashHistory所標識的地址,第二個#號后為hashHistory中location的hash值,如:

如同browserHistory一樣,hashHistory也可調用hashHistory.block阻止導航;導航時也可以傳入相對路徑參數。

注意,如果hashHistory.push設置了state參數,則第4版本的history庫會給出警告:

由于考慮兼容性問題,第4版本的history庫沒有使用pushState的底層接口。因此,對應的歷史棧狀態也無法存儲,history進行了忽略并提示開發者。
對于hashHistory.push的參數,也可以為location對象,其類型描述如下:


若hashHistory.push方法的第一個參數為對象,則可分別設置hashHistory的pathname、search和hash等:

如果希望hashHistory也能傳遞一個state對象,則可在location對象中設置state:

第4版本的history庫不建議在hashHistory中使用state,雖然可通過location對象傳遞state,但是其作為頁面級別的state,不具備持久化state的能力。這時,僅能從hashHistory.location.state中讀取到對象{some:'state'},而不能從window.history.state中讀取到。例如在瀏覽器中執行一次后退再前進的操作,由于window.history.state沒有存儲狀態,這時讀取hashHistory.location.state,讀取到的值將為空。而browserHistory可以再次讀取到state值,所以需要注意,hashHistory.location.state在導航過程中并不能如browserHistory一樣其state值能得到再現。由于pushState等HTML5接口已經被廣泛使用,在history庫未來的第5版本中將使用pushState來模擬hashHistory,因此持久化的state設置會得到支持。此時,hashHistory設置的state也可從window.history.state中讀取到。相關的持久化能力可查看1.2.1節。
2.history.replace
使用history.replace可替換歷史棧中的棧記錄。history.replace的使用方式與history.push類似,其簽名如下:

調用history.replace同樣會修改瀏覽器地址,但其如browserHistory的replace方法一樣,僅替換某個歷史記錄:

在history庫源碼中,hashHistory使用window.location.replace接口,以達到僅替換歷史棧記錄而不添加歷史棧記錄的目的:

注意,與browserHistory不同的是,hashHistory在創建時沒有keyLength選項,這對應到hashHistory.push、hashHistory.repalce方法不產生key值,即hashHistory.location.key為undefined:

這里需要提一下base元素基準路徑處理問題,如果HTML文檔流中存在base元素,且base元素的href屬性不為空,則在history v4.10.0中,替換hash的方法如下:

history.replace調用的replaceHashPath會在window.location.href沒有#號時,得到window.location.href.slice(0,0)的結果。由于window.location.href.slice(0,0)返回空字符串,因此實際會調用:

但是對于有base元素的HTML文檔來說:

window.location.replace僅傳入hash字符串的調用會將window.location.pathname改成base的值,原pathname將丟失,如:

假若當前路徑為https://example.com/foo/baz,且有href屬性值為/base/的base元素存在,在調用window.location.replace("#path")后,原路徑中/foo/baz將會丟失。若要避免丟失,則需要將/foo/baz也一起傳入,如window.location.replace("/foo/baz/#path")。
在history v4.10.1中,replaceHashPath方法改為了:

在調用window.location.replace時會保留pathname部分,history v4.10.1修復了這個問題,使用historyv4.10.1以下版本的開發者需注意這個問題。
3.history.go
其實現與browserHisotry的history.go一致,調用全局的window.history.go方法:


當調用history.go方法時,history的狀態更新由hashchange事件監聽函數進行處理,具體內容將在2.5.4節介紹。
注意,在Firefox瀏覽器中,通過widnow.history.go移動指針而改變hash會使得頁面重新刷新加載,這與Chrome等瀏覽器的行為不一致。
- OpenStack Cloud Computing Cookbook(Third Edition)
- Web前端開發技術:HTML、CSS、JavaScript(第3版)
- 大學計算機基礎(第三版)
- Mastering OpenCV Android Application Programming
- Manga Studio Ex 5 Cookbook
- React Native Cookbook
- 營銷數據科學:用R和Python進行預測分析的建模技術
- 零基礎學Java(第4版)
- Mastering Yii
- PLC編程及應用實戰
- PHP+MySQL網站開發項目式教程
- SQL基礎教程(第2版)
- 編程可以很簡單
- Unity Character Animation with Mecanim
- Docker:容器與容器云(第2版)