一、hash、hashchange 事件介紹
1、hash 是什么?
hash 屬性是一個可讀可寫的字符串,該字符串是 URL 的錨部分,一般有當前頁面中 href 中 # 地址觸發。hash 即 URL 中 # 字符后面的部分,具有如下特點:
- 使用瀏覽器訪問網頁時,如果網頁URL中帶有hash,頁面就會定位到 id(或name)與hash值一樣的元素的位置;
- hash 還有另一個特點,它的改變不會導致頁面重新加載;
- hash 值瀏覽器是不會隨請求發送到服務器端的;
- 通過 window.location.hash 屬性獲取和設置 hash 值。
window.location.hash 值的變化會直接反應到瀏覽器地址欄(#后面的部分會發生變化),同時,瀏覽器地址欄 hash 值的變化也會觸發 window.location.hash 值的變化,從而觸發 onhashchange 事件。
2、hashchange 事件
- 當URL的片段標識符更改時,將觸發hashchange事件(跟在#符號后面的URL部分,包括#符號)
- hashchange事件觸發時,事件對象會有hash改變前的URL(oldURL)和hash改變后的URL(newURL)兩個屬性
window.addEventListener('hashchange', function(e) { console.log(e.oldURL); console.log(e.newURL) }, false);
二、實際應用場景
1、hash 的簡單應用
頁面中有 3 個不同的a標簽,當點擊不同的a時給filterText賦予不同的值,可利用window.onhashchange事件來實現,這樣避免了給每個a標簽分別注冊事件
<a href="#/"></a>
<a href="#/active"></a>
<a href="#/completed"></a>
//此函數監聽hash值的變化,來給判斷哪個按鈕被點擊,從而給filterText賦值
let filterText = 'all' window.onhashchange = function () { switch(window.location.hash) { case '#/': filterText = 'all'
break
case '#/active': filterText = 'active'
break
case '#/completed': filterText = 'completed' } }
2、hashchange 事件的應用
移動端里有這樣一個功能,點擊小圖時在當前頁面上展示大圖,這應該是很常見的場景:
CSS和Javascript具體怎么實現的就不再啰嗦了,這里要考慮的問題是:當進入大圖展示狀態時,如何返回?這是手機的頁面,對於用慣APP的用戶來說,他很可能會點擊左下角的返回鍵。然而這是個瀏覽器,返回就意味着回到上一頁而不是退出大圖展示狀態。
下面講解一下如何利用 hashchange 解決這個問題。我們需要了解的是:當URL的hash改變時,雖然頁面不會重新加載,但仍然會被記錄到瀏覽器的歷史記錄中。
也就是說,如果依次訪問 a.html、b.html、b.html#abc,然后點擊后退,此時會返回 b.html 而不是 a.html。而且,由於hash改變了,所以會觸發hashchange事件。這樣一來,只要在進入大圖展示狀態時加上一個特定的 hash,點擊返回鍵觸發 hashchange 時退出此狀態即可。代碼也很簡單:
// 假設大圖展示狀態的hash為imgSlider
window.addEventListener('hashchange', function(e) { var re = /#imgSlider$/; if ( re.test(e.oldURL) && !re.test(e.newURL) ) { // 假設imgSlider為大圖展示組件對象
imgSlider.hide(); } }, false);
3、hashChange 巧妙監聽原生輕應用跳轉
//頁面初始化中添加hashchange的監聽
initialize:function(){ window.addEventListener("hashchange", this.pageHashChange,false); }, //隱藏
pageHashChange(){ if(startTimePicker) startTimePicker.hide(); if(endTimePicker) endTimePicker.hide(); if(remindPicker) remindPicker.hide(); },
4、一個小的業務場景:當用戶進入一個頁面按手機系統自帶的返回按鈕時,彈出一個挽留框,並阻止用戶跳出這一行為。
解決方案:
(1)在進入當前頁面時,通過加 hash 或者 pushState(null,null,window.location.href),在 history 棧中增加一條和當前路徑相同的地址
(2)當用戶點擊返回時,會觸發window.onhashchange 或 window.onpopstate 事件,讓 hash 或 pushState 行為在用戶要返回時被監聽到,此時彈出挽留框,頁面還是之前的頁面沒有變化。