Javascript擁有許多可以操作瀏覽器歷史記錄的方法,不管是普通頁面跳轉,還是單頁應用哈希值變化,我們都會經常與這些方法打交道,尤其在單頁應用中這些方法幾乎是頁面路由的核心方法。本文將詳細討論這些方法。
location是最有用的BOM對象之一,它提供了與當前窗口中加載的文檔有關的信息,還提供了一些導航功能。事實上,location對象既是window對象的屬性,又是document對象的屬性。換句話說,window.location和document.location是同一個對象。這里推薦大家使用document.location的寫法,以適應非瀏覽器文檔環境。 除去為a標簽設置的href屬性,大家最常用的跳轉方式一定就是:window.location.href=”xxx”;實際上,上面這句代碼真正執行的是location.assign方法。簡而言之,下面三中URL跳轉的寫法完全等同,都會立即打開新的URL并在瀏覽器的歷史記錄中生成一條記錄:
document.location.assign("xxx");document.location="xxx";document.location.href="xxx";需要注意的是,如果通過這種方式跳轉的URL與當前URL完全相同,則頁面會刷新,但是瀏覽器歷史記錄不會新增。
功能幾乎與location.href=”xxx”;
完全相同,只有一個區別,location.replace會在瀏覽器的歷史記錄中生成一條記錄,并替換前一條記錄。舉個例子,當我們打開“a.html”頁面,頁面內有如下兩行代碼:
瀏覽器先通過location.href
的方式跳轉到c.html,接著又使用location.replace
跳轉到b.html。此時點擊瀏覽器的后退按鈕,瀏覽器會直接返回a.html,因為c.html這條歷史記錄被replace覆蓋了。
我們可以通過如下代碼形式來監聽瀏覽器URL的哈希值變化:
window.addEventListener("hashchange",function(){ //do something},false);//以下代碼都會觸發hashchange事件document.location.hash="#a=1";document.location.href="b.html#b=1";document.location.replace("c.html#c=1");當我們通過改寫location的方式引起瀏覽器URL哈希值變化時,hashchange事件就會觸發。如果URL重寫導致了頁面刷新(例如改變了URL查詢參數,或者直接跳向一個跨域地址),hashchange事件會直接被跳過。請注意,URL哈希值變化不一定總是會觸發hashchange事件,下面要介紹的方法就是改動URL但不觸發hashchange。
pushState方法接收三個參數:一個記錄歷史狀態的對象(該對象會在popstate事件觸發時被傳入,有640K的大小限制);一個代表歷史記錄標題的字符串;一個與當前URL同源的地址。典型的使用方式如下:
history.pushState({}, "", "b.html");history.pushState()
方法會將URL設置為一個同源URL值,在此之后發送的Ajax請求的Referrer頭部都會使用這個新的值,同時在瀏覽器歷史記錄中生成一條新的歷史記錄。但是pushState方法不會刷新頁面,pushState引起的URL哈希值變化也不會觸發hashchange事件。pushState如果設置了一條與當前URL完全相同的地址,瀏覽器的歷史記錄中仍然會新增一條記錄。
該方法與history.pushState
基本相同,唯一的區別就是replaceState會像location.replace
一樣覆蓋先前歷史記錄。 關于history.pushState和history.replaceState的更多介紹: https://developer.mozilla.org/zh-CN/docs/DOM/Manipulating_the_browser_history
我們可以通過如下代碼形式來監聽瀏覽器的popstate事件:
window.addEventListener("popstate",function(event){ //do something},false);與hashchange事件類似,popstate會在任何URL變化時觸發(hashchange只會在哈希值變化時觸發),并且history.pushState和history.replaceState也不會觸發popstate事件。只有在瀏覽器后退、前進、重寫哈希值的情況下才會觸發popstate事件。如果URL重寫導致了頁面刷新(例如改變了URL查詢參數,或者直接跳向一個跨域地址),popstate事件會直接被跳過。 這里請注意一下代碼中傳給事件函數的參數“event”,event參數中包含state對象,這個state對象就是在調用history.pushState和history.replaceState方法是傳入的第一個狀態參數,我們可以通過這種狀態傳遞方式來對歷史記錄進行一定處理。
新聞熱點
疑難解答