history 路由:監聽 url 中的路徑變化,需要客戶端和服務端***同的支持;
我們壹步步實現這兩種路由,來深入理解下底層的實現原理。我們主要實現以下幾個簡單的功能:
1.監聽路由的變化,當路由發生變化時,可以作出動作;
2.可以前進或者後退;
3.可以配置路由;
當頁面中的 hash 發生變化時,會觸發hashchange事件,因此我們可以監聽這個事件,來判斷路由是否發生了變化。
事件hashchange只會在 hash 發生變化時才能觸發,而第壹次進入到頁面時並不會觸發這個事件,因此我們還需要監聽load事件。
在 history 路由中,我們壹定會使用window.history中的方法,常見的操作有:
back():後退到上壹個路由;
forward():前進到下壹個路由,如果有的話;
go(number):進入到任意壹個路由,正數為前進,負數為後退;
pushState(obj, title, url):前進到指定的 URL,不刷新頁面;
replaceState(obj, title, url):用 url 替換當前的路由,不刷新頁面;
調用這幾種方式時,都會只是修改了當前頁面的 URL,頁面的內容沒有任何的變化。但前 3 個方法只是路由歷史記錄的前進或者後退,無法跳轉到指定的 URL;而pushState和replaceState可以跳轉到指定的 URL。如果有面試官問起這個問題“如何僅修改頁面的 URL,而不發送請求”,那麽答案就是這 5 種方法。
如果服務端沒有新更新的 url 時,壹刷新瀏覽器就會報錯,因為刷新瀏覽器後,是真實地向服務器發送了壹個 http 的網頁請求。因此若要使用 history 路由,需要服務端的支持。
當我們用 history 的路由時,必然要能監聽到路由的變化才行。全局有個 popstate 事件,別看這個事件名稱中有個 state 關鍵詞,但 pushState 和 replaceState 被調用時,是不會觸發觸發 popstate 事件的,只有上面列舉的前 3 個方法會觸發
針對這種情況,我們可以使用 window.dispatchEvent 添加事件:
然後就可以添加對這兩個方法的監聽了: