這篇文章主要是記錄下HTML5中history提供的pushState, replaceStateAPI。最後透過這些API自己實現小型的路由。
關於window.history提供的API請參閱Mozilla文檔
其中history提供的pushState和replaceState2個API提供了操作瀏覽器歷史堆疊的方法。
其中pushState:
history.pushState(data, null, '#/page=1'); pushState接收3个参数,第一个参数为一个obj,表示浏览器 第二个参数是document.title的值,一般设定为`null` 第三个参数string,用以改变 当前url
pushState方法在改變url的同時向瀏覽器歷史堆疊中壓入新的歷史記錄。
接收url的參數為string類型,用以改變當前地址欄的url.需要注意的一點就是這個參數不能和跨域,即協議,域名,端口必須都是相同的,如果出現跨域的情況,即會提示:
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://www.baidu.com/' cannot be created in a document with origin 'http://commanderXL.com' and URL
Example:
打开www.baidu.com history.pushState(null, null, '?page=1') //地址栏变成 www.baidu.com/?page=1 history.pushState(null, null, '#page=2'); //地址栏变成 www.baidu.com/#page=2
其中replaceState:
history.replaceState(null, null, '#page=2');
replaceState接收的參數pushState相同,但是最終的效果是:地址列url會根據接收到的參數而變化,但是瀏覽器並未在當瀏覽器歷史棧中增加瀏覽器的歷史記錄,而是取代目前的瀏覽器歷史記錄。
透過pushState和replaceState雖然能改變URL,但是不會主動觸發瀏覽器reload。
window物件也提供popstate方法:
window.addEventListener('popstate', function() { });
這個方法用以監聽瀏覽器在不同歷史記錄中進行切換,而觸發對應的事件。
在瀏覽器提供的history物件上還有go, back方法,用以模擬使用者點擊瀏覽器的前進後退按鈕。在某個web應用程式當中,例如點擊了標籤,發生了頁面的跳躍。這時呼叫history.back();方法後頁面回退,同時頁面發生刷新,這時window.onpopstate無法監聽這個事件。但如果是透過pushState或replaceState來改變URL且不發生瀏覽器刷新的話,再使用history.back()或history.go(),這樣popstate事件會被觸發。
history.pushState({page: 1}, null, '?page=1'); history.pushState({page: 2}, null, '?page=2'); history.back(); //浏览器后退 window.addEventListener('popstate', function(e) { //在popstate事件触发后,事件对象event保存了当前浏览器历史记录的状态. //e.state保存了pushState添加的state的引用 console.log(e.state); //输出 {page: 1} });
PS: 透過pushState在url上新增?page=1可以透過location.search去取得search的內容。不過如果透過location.search去改變url的話是會主動觸發瀏覽器reload的。這個特性可以和下面將的關於hash的內容比較下。
API大致了解了,那麼這些方法可以運用到哪些地方呢?一個比較常用的場景是就在單頁應用中,透過這些API完成前端的路由設計,利用pushState, replaceState可以改變url同時瀏覽器不刷新,並且透過popstate監聽瀏覽器歷史記錄的方式,完成一系列的異步動作。
addRoute('/login', function() { //do something }) //路由处理 const routeHandle = (path) => { Router.forEach((item, index) => { if(item.path === path) { item.handle.apply(null, [path]); return true; } }) return false; } //拦截默认的a标签行为 document.addEventListener('click', function(e) { let dataset = e.target.dataset; if(dataset) { if(routeHandle(dataset.href)) { //阻止默认行为 e.preventDefault(); } } })
大致的實現思路就是,透過添加路由訊息,然後攔截標籤的預設行為,並與註冊的路由資訊進行匹配。若符合成功呼叫對應的handle方法.
不過pushState和replaceState方法在低版本的IE瀏覽器下相容性不是很好。所以可以進行降級使用hash來進行路由設計。
hash?請戳我。
可以透過location.hash取得url上第一個#(fragment)及後面的內容。同時也能透過location.hash改寫其內容,且不會主動觸發瀏覽器reload。 有些功能是不是跟pushState和replaceState一樣? 所以為了相容到低版本的瀏覽器,可以透過監聽#變化來進行路由設計。
那麼如何去監聽呢? 比較粗暴的一種方式就是polling。
var oldHash = location.hash; setTimeInterval(function() { if(oldHash !== location.hash) { //do something oldHash = location.hash; } }, 100);
不過,H5也提供了一個API: hashchange。它的就可以直接取代上面的polling方法,來監聽#的變化。
window.addEventListener('hashchange', function() { routeHandle(locaiton.hash); });
這個小型的路由設計可以參考我的github.
稍微總結下:
上面主要介紹了history提供的一些API,hash的相關知識。在平時可以運用到SPA當中,Gmail就是透過hash來進行路由設計的。它相對於頁面跳轉來說:
頁面只需要載入一次。後面的頁面切換可以透過ajax去請求資料。頁面體驗更加流暢;
可以利用本地緩存,優化頁面體驗。在不同頁面切換的過程中更加流暢;
可進行隨選載入...
等等一些實用的好處吧。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。