路由的概念起源於網絡工程,例如我們日常中的路由器,所謂前端路由的概念簡單歸納就是前端可以自己根據不同url地址來展示不同的內容
在Ajax
出現之前,都是使用後端路由來控制頁面的渲染,服務器在接收到不同的url
地址後,服務器通過解析url
去拼接不同的html
,然後返回給前端進行渲染,所以這也是後端路由的一個弊端,每一次的切換都是需要刷新整個頁面,同時如果是大量的頁面每一個頁面都需要做一段邏輯處理也造成了後端實在不堪重負
前端路由的出現很好的解決了這個問題,前端路由不需要刷新整個頁面,也就不會出現每一次切換都會出現閃爍,也沒有網絡延遲,大大提升了用戶體驗,減輕了服務器的壓力,但是同時也存在問題是前端的安全性問題
目前前端路由的實現主要採用兩個方法
- hash
- history
hash
hash就是我們通常說的錨點,一般用於內容的快速定位,但是hash值有一個特點,就是會改變url,但是不會觸發瀏覽器的刷新,利用這個特點,我們配合可以檢測到hash值變化的hashchange
事件就能比較容易實現前端路由
window.addEventListener("hashchange",function () {
console.log("錨點值改變了");
//發送ajax請求,局部刷新頁面,加載模塊等操作
})
history
history是window
對象的一部分,包含用戶在瀏覽器中訪問過的歷史記錄
-
屬性
length:該屬性會返回瀏覽器中歷史記錄的數量
state:返回一個歷史記錄中頂部記錄的狀態值
scrollRestoration:允許瀏覽器自定義設置默認的滾動行爲,該屬性有兩個值,auto和manual
這裏關於
scrollRestoration
屬性我們多說一點,在JavaScript中有一個叫做scrollTo
的方法,該方法可以指定滑動位置,例如可以用來控制我們每一次聊天內容都固定在窗口的底部test.scrollTo(0,test.scrollHeight)
但是有時候並不會生效,這個有可能就是
scrollRestoration
的原因,因爲瀏覽器是默認保持滾動位置的,也就是說瀏覽器設置history
的默認值是auto
,我們需要將其設置爲manual
history.scrollRestoration="manual"
這個是時候就可以正常的按照我們的需求每一次固定到窗口底部了
如果有兼容性問題採用如下寫法
setTimeout(() => { window.scrollTo(0, document.body.scrollHeight) })
- 方法
back:返回上一條歷史記錄
forward:前往下一條歷史記錄
go:前往指定的歷史記錄,history.go(1)相當於history.forward(),history.go(-1)相當於history.back()
同時在js中也存在一個popstate
的方法可以監測到瀏覽器的前進/後退,同時在該方法中可以獲取到歷史記錄的狀態對象
window.addEventListener("popstate",function (e) {
console.log(e.state)
})
在HTML5中新增加了兩個方法pushState,replaceState
這兩個方法都是在不觸發瀏覽器的刷新機制下改變瀏覽器的url
,不同之處在於pushState
相當於在瀏覽器歷史記錄棧中添加了一條我們自定義的歷史記錄,而replaceState
相當於用我們自己設置的歷史記錄替換掉了瀏覽器當前的歷史記錄棧中的第一條,所以pushState
會改變history
的length
長度,而replaceState
則不會
這兩個方法都接收三個參數
- state,一個指定網址相關的狀態對象
- title,指定新頁面的標題,但是目前被大部分瀏覽器忽略
- url,指定新的網址,但是必須是和當前網址是同源的
這兩個方法都是不能被popstate監測到的,但是在執行兩個方法的時候是能夠觸發history.state的從而我們可以拿到我們每一次增加/替換歷史記錄時的state
,可以通過觀察者模式來實現對history
狀態的監聽
let page=1
ahead.addEventListener("click",function () {
page++;
window.history.pushState({page : page}, 'test', '#test');
console.log(window.history.state);
//通過state值可以加載不同模塊/發送數據請求,局部刷新頁面
})
window.addEventListener("popstate",function (e) {
console.log(e.state)
//在用戶點擊後退、前進時會被postate監測到,同時也會獲取到state
})