林大媽的JavaScript進階知識(四):HTML5 History API
- 2019 年 10 月 3 日
- 筆記
HTML5中新增了History API,它用於管理瀏覽器路由跳轉的一個url棧。History是window對象的一部分,它也是一個對象,因此稱它是BOM(類似DOM,Browser Object Model)中的一份子。History對象包含了用戶在瀏覽器端訪問過的所有url。
一、為什麼存在History對象
當使用location.herf或a標籤中的非錨點方式的href進行頁面跳轉時,會造成整個頁面的刷新。但目前來說,越來越多的單頁應用利用ajax技術進行異步請求,僅僅依靠數據變化更改視圖而不刷新頁面,像瀏覽器的前進和後退這些按鈕的功能定位就會變得十分尷尬。例如我們訪問一個博客頁,在列表中點擊某個博客跳轉到文章頁面,但文章是利用ajax技術加載的,也就是頁面的url沒有發生變化。此時我覺得這篇博客很有教育意義,於是將它分享給了我的朋友,如果不對路由進行處理,我的朋友點擊這個url打開的頁面將是博客列表而不是這篇被分享的博客。因此我們需要得到History對象的幫助。同時,History對象本被設計以表示與操作瀏覽器的訪問歷史,但由於隱私原因,它被封裝好不能使用腳本訪問其中的url,而只允許我們使用暴露出的幾個方法:go()、back()和forward()來進行跳轉。
二、History相關方法
我們已經介紹了History中存在的部分內容以及它為什麼要誕生。然後我們就要關注怎麼使用它。我們首先要了解它的內建方法:
1. back(),forward()和go(n)方法
這三個方法的使用非常的直觀,如它們字面的意思一樣,就是直接調用history.back()和history.forward(),還有history.go(n)。其中go方法中填入參數為希望跳轉到多少個頁面以前/以後,填入正數n相當於循環調用n次forward,負數-n相當於循環調用n次back。假如我先後訪問了
① www.baidu.com,
② www.google.com,
③ www.cnblogs.com(現在頁面在此處):
當我在瀏覽器調試工具中這樣調用:
1 history.back(); 2 //跳轉到谷歌首頁 3 history.forward(); 4 //跳轉到博客園首頁 5 history.go(-2); 6 //跳轉到百度首頁 7 history.go(2); 8 //跳轉到博客園首頁
2. pushState(stateData, title, url),replaceState(stateData, title, url)
這兩個方法也是單頁面應用實現的實質之一,它們均不會造成頁面的刷新,且都不能跨域。而它們的功能可以從名字中看出,分別是在history棧中創建新的訪問記錄和修改當前的訪問記錄。需要注意的是,pushState會將當前url往後的記錄清除,再將新的url記錄壓入history棧中。
3. location.href
這個location對象中的屬性會直接導致刷新頁面,需要與以上的兩個方法進行區分。
4. window.onpopstate,window.onhashchange
這兩個全局方法被創建用以監聽訪問的變化。它們的區別是,一個只有在頁面發生刷新的情況下調用;一個在url的錨點(由於“#”後面的內容不會被識別,修改它頁面不會發生跳轉,因此稱為錨點)變化時就會調用。
三、以圖詳解變化
上圖簡單介紹了History API中各方法調用時url跳轉及頁面顯示情況。其中橙色表示當前頁面顯示的內容。
總結:由於Ajax技術的出現,單頁面應用的興起,現代的Web技術中需要有正確管理調度路由的工具,History API於是誕生。現代的前端框架中也同樣配備了以History封裝的路由管理工具,如,Vue-router,React-router-DOM等。通過了解History中go、pushState以及replaceState方法,我們可以進一步學習框架內部的實現原理。只有懂得原理才能觸類旁通。