前端路由以及瀏覽器回退,hash & history & location


一、前言

其實不止一次想監聽瀏覽器的回退方法,比如

在 list.html 頁滾動加載了幾頁列表,點到 detail.html 看詳情,反回來時又得重新加載幾頁

H5 有背景音樂的,跳頁就得重新放,體驗實在不妙,等等

再其他就是體驗上的優化了,雖然可以添加返回按鈕,但手機的回退鍵還是很常用的。

再加上 ajax 的無刷新體驗,單頁面應用可謂是一大裝逼利器。

 

二、前端路由的好處

(偽)換頁面時還可以添加動畫,絲滑流暢的操作體驗實在不能更棒,另外相較后端路由,前端路由也算是減輕了服務區負荷...

也正基於此,根據不同 url 渲染不同視圖這種路由的概念被提上台面,讓渲染哪一個可以得到方便的管理。

 

三、前端路由的壞處

前端路由也是有利有弊,它的不足在於

1. 安全性,改改路由就能跳到某頁面,肆意進入不同流程,想想還是有點瘮人的

2. 狀態恢復,比如第一頁添了表單,跳到第二頁再返回,這些表單可能得清空之類的問題

 

四、實現前端路由

其實路由也就兩步,實現 url 變化 & 捕捉變化進行不同的頁面邏輯

1. 改變 url

location api 的 reload / replace 方法,修改 href / hash / search 等屬性等,

history api 的 back / go 方法,以及比較新的 pushState / replaceState 方法...

改變 url 的方式太多了,

需要注意的是哪些是會刷新頁面的,哪些是會改 url 但不刷新頁面的...

2. 捕捉 url 變化

主要得靠 window 的事件 hashchange 和 popstate

用 setInterval 持續監聽(每 100ms 比較 oldUrl 和 nowUrl)也不是不可以,但你也懂得性能是個好東西

注意:pushState / replaceState 不會觸發 popstate 事件,其他是否觸發問題你可以繼續嘗試

3. 簡單的實現與封裝

易懂的封裝:

function Router() {
    this.routes = {};
    window.addEventListener('load', this.resolve.bind(this), false);
    window.addEventListener('hashchange', this.resolve.bind(this), false);
}
Router.prototype.route = function(path, callback) {
    this.routes[path] = callback || function(){};
}
Router.prototype.resolve = function() {
    this.curHash = location.hash.slice(1) || '/';
    typeof this.routes[this.curHash] === 'function' && this.routes[this.curHash]();
}

簡單的案例:

<ul>
    <li><a href="#blue">藍色</a></li>
    <li><a href="#yellow">黃色</a></li>
</ul>
<ul>
    <li><a href="#red">紅色</a></li>
</ul>
var router = new Router();
router.route('blue', function(){
    document.body.style.background = 'lightblue';
});
router.route('yellow', function(){
    document.body.style.background = 'yellow';
});
router.route('red', function(){
    document.body.style.background = 'red';
});

DEMO1: https://foreverz133.github.io/demos/single/router.html 

DEMO2: https://foreverz133.github.io/demos/single/history.html

 

五、其他

1. 不是所有頁面都需要改變 url,因為它會牽扯到回退

2. 瀏覽器的回退在體驗上對前端是道比較難回答的題,比如回退兩頁,不返回登錄/支付等

3. 在轉場之間加上動畫,當然要完成這效果就得使用 click 和 transitionEnd 等事件了

4. 狀態控制,最便捷(並非最佳)的辦法是全局一個對象去保存這些狀態,每次進行判斷和初始化操作

5. 當然如果你會 ReactJS 等模塊化渲染的話,路由還可以更厲害

6. 還要比往常遇到更多優化上的問題,比如資源加載/數據更新/操作流暢度等

7. 梳理邏輯和確定狀態,這些前期的事遠比書寫更重要,不然你會被改死的,講真!

 

本文所提路由還太狹隘,畢竟路由是前后端都有的東西,url 也僅僅是指向某資源,所以它還會涵蓋處理數據/數據傳遞等更多方面

 

六、總結

單頁面應用(SPA)對前端的要求成倍增加,對開發者來說其實是好事,

有挑戰進度會更快,不過和后端/策划的契合度也要相應提高才行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM