各位好,延續昨天的內容,今天要說明如何透過監聽事件,來得知網址產生變化後的行為:
我們知道可以用Javascript讓網址產生了變化,但仔細想想,要怎麼知道在網址變化後產生不同的內容呢?答案是我們可以使用監聽事件,網址變化後才做render及其他的行為。以下簡單介紹兩種可以監聽網址變化的方式:
結合前一天的history.pushState()例子來說明,我們先對瀏覽器增加監聽事件,並且試試增加幾筆歷史紀錄。console執行程式碼如下所示:
//監聽歷史紀錄變化
window.addEventListener('popstate', function(event) {
console.log("location: " + location.href + ", state: " + JSON.stringify(event.state));
})
//加入歷史紀錄
history.pushState(null,null,'/hello')
history.pushState(null,null,'/world')
在pushState時並沒有看到console有監聽處裡的輸出紀錄,但當切換上/下一頁,可以看到console產生紀錄,這是為什麼呢?查看MDN,其中一段說明:
需要注意的是調用history.pushState()或history.replaceState()不會觸發popstate事件。只有在做出瀏覽器動作時,才會觸發該事件,如用戶點擊瀏覽器的回退按鈕(或者在Javascript代碼中調用history.back()或者history.forward()方法)
原來如此,由於pushState本身並不會觸發事件,只有在瀏覽紀錄變化時才會觸發,所以我們就可以在同一頁增加歷史紀錄,並在切換上/下頁時觸發後進行render。
hashchange是針對hash部分變化時的監聽,這邊同樣地在console輸入以下程式碼:
//監聽hash變化
window.addEventListener('hashchange', function(event) {
console.log("location: " + location.href + ", hash: " + location.hash);
})
//改變hash內容
location.hash='hello'
可以發現在console順利看到兩行紀錄,在hash變化當下即會觸發行為,並同時列入瀏覽紀錄。既然列入瀏覽紀錄,不如試試切換上/下頁吧。
沒問題,一樣監聽的到,這樣後續的render代表也不是問題了。雖然hash方式不像是一般的網址列乾淨漂亮,但使用上較容易達成,因此後面也會用這樣的方式示範。
我們知道了Javascript可以動態使網址產生變化,也可以使用監聽事件來判斷網址動態變化,並且取得網址資訊,那麼意味著前端也可以處理路由(router)的功能。用MVC開發架構來說明,Controller在前端做路由管理,經由預先設定匹配的路徑(routes),找出對應的View元件產生渲染(render)就可以產生出畫面。目前各家框架都有支援router,例如React的React-router-dom、Vue的Vue Router、Angular的Angular Router等,後續我們也會搭配hashchange事件來實作router。