前端路由實現(xiàn)

路由實現(xiàn)原理谬运,就是根據(jù)不同的 url 隙赁,在頁面上顯示相應(yīng)的內(nèi)容。而瀏覽器 url 變化時梆暖,會造成頁面的刷新伞访。前端路由要解決問題就是,在改變 url 的情況下式廷,保證頁面的不刷新咐扭。

hash

url 中的 hash 改變時,瀏覽器不會向服務(wù)器發(fā)送請求滑废,頁面不會刷新蝗肪。

hash 應(yīng)用的常見場景如,用 hash 實現(xiàn)頁面導(dǎo)航蠕趁。如下代碼薛闪,點擊 a 標(biāo)簽 '聯(lián)系'(a 標(biāo)簽的 href 屬性值為 #contact),瀏覽器 url 會變成http://www.xxx.com/#contact俺陋,頁面會定位到元素 idcontact 的位置豁延。

<!DOCTYPE html>
<html>
    <head>
        <style>
            .nav li{
                float: left;
            }
            article{
                height: 600px;
                text-align: center;
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <ul class="nav">
            <li><a href="#home">首頁</a></li>
            <li><a href="#about">關(guān)于</a></li>
            <li><a href="#work">作品</a></li>
            <li><a href="#contact">聯(lián)系</a></li>
        </ul>
        <artice>
            <section id="home">首頁</section>
            <section id="about">關(guān)于</section>
            <section id="work">作品</section>
            <section id="contact">聯(lián)系</section>
        </artice>
    </body>
</html>

另外,urlhash 變化時腊状,會觸發(fā) hashchange 事件诱咏,該事件上有兩個屬性,oldURLnewURL缴挖,分別表示跳轉(zhuǎn)前的 url 和跳轉(zhuǎn)后的 url袋狞。通過分析 event.newURL 字段,配合 AJAX 發(fā)送請求映屋,即可讓頁面展示相對應(yīng)的內(nèi)容苟鸯。

window.addEventListener('hashchange', function(event) {
  console.log('Hash changed from ' + event.oldURL);
  console.log('Hash changed to ' + event.newURL);
});

history api

html5 的 history api 可以實現(xiàn)無刷新更改地址欄鏈接,再配合 AJAX 即可實現(xiàn)頁面無刷新跳轉(zhuǎn)棚点。具體實現(xiàn):當(dāng)用戶點擊導(dǎo)航鏈接 a 標(biāo)簽時早处,通過 replaceState 將瀏覽器地址欄的 url 更改為 a 標(biāo)簽 href 屬性的值,同時配合 AJAX 獲取數(shù)據(jù)瘫析,替換頁面 DOM 中的內(nèi)容砌梆。

history 作為一個全局變量(即 window.history)默责,不繼承任何屬性,在 html4 標(biāo)準(zhǔn)中么库,history 有如下屬性和方法:

  • History.length 屬性: 返回一個整數(shù)傻丝,該整數(shù)表示會話歷史中元素的數(shù)目甘有,包括當(dāng)前加載的頁诉儒。例如,在一個新的選項卡加載的一個頁面中亏掀,這個屬性返回1忱反。
  • History.back() 方法:前往上一頁, 用戶可點擊瀏覽器左上角的返回按鈕模擬此方法。等價于history.go(-1).
  • History.forward() 方法:在瀏覽器歷史記錄里前往下一頁滤愕,用戶可點擊瀏覽器左上角的前進(jìn)按鈕模擬此方法温算。等價于 history.go(1).
  • History.go() 方法:通過當(dāng)前頁面的相對位置從瀏覽器歷史記錄( 會話記錄 )加載頁面。比如:參數(shù)為-1的時候為上一頁间影,參數(shù)為1的時候為下一頁. 當(dāng)整數(shù)參數(shù)超出界限時医寿,那么這個方法沒有任何效果也不會報錯脚祟。調(diào)用沒有參數(shù)的 go() 方法或者不是整數(shù)的參數(shù)時也沒有效果。

html5 標(biāo)準(zhǔn)中,history新增了 history.pushState(state, title, url)扩劝、history.replaceState(state, title, url) 方法,和 popstate 事件粗井。

  • History.pushState(state, title [, url]) 方法:往瀏覽歷史堆棧的頂部添加一個狀態(tài)枝哄,不刷新頁面。pushState() 帶有三個參數(shù):一個狀態(tài)對象键科,一個標(biāo)題(現(xiàn)在被忽略了)闻丑,以及一個可選的URL地址。

    state 為一個對象或 null勋颖,它會在觸發(fā) window 的 popstate 事件(window.onpopstate)時嗦嗡,作為參數(shù)的 state 屬性傳遞過去;如果你像 pushState() 方法傳遞了一個序列化表示大于 640k 的 state 對象饭玲,這個方法將扔出一個異常侥祭。如果你需要更多的空間,推薦使用 sessionStorage 或者 localStorage咱枉。title 為頁面的標(biāo)題卑硫,但當(dāng)前所有瀏覽器都忽略這個參數(shù)。URL 為頁面的 URL蚕断,不寫則為當(dāng)前頁欢伏;新 URL 必須和當(dāng)前URL在同一個源下;否則亿乳,pushState() 將丟出異常硝拧。

  • History.replaceState(state, title [, url]):更改當(dāng)前頁面的歷史記錄值径筏,不刷新頁面。參數(shù)同上障陶。這種更改并不會去訪問該URL滋恬。
  • **popstate ** 事件:當(dāng)活動歷史記錄條目更改時,將觸發(fā) popstate 事件抱究。如果被激活的歷史記錄條目是通過對 history.pushState() 的調(diào)用創(chuàng)建的恢氯,或者受到對 history.replaceState() 的調(diào)用的影響,popstate 事件的 state 屬性包含歷史條目的狀態(tài)對象的副本鼓寺。

    需要注意的是調(diào)用 history.pushState() 或history.replaceState() 不會觸發(fā) popstate 事件勋拟。只有在做出瀏覽器動作時,才會觸發(fā)該事件妈候,如用戶點擊瀏覽器的回退按鈕敢靡。

    當(dāng)我們需要監(jiān)聽該事件并作出相應(yīng)響應(yīng)時,我們應(yīng)該這樣組織代碼:

window.addEventListener("popstate", function(e) {
    var state = e.state;
    // do something...
});

【1】https://juejin.im/post/5aebc4a26fb9a07acc11924d

【2】https://www.renfei.org/blog/html5-introduction-3-history-api.html

【3】https://hijiangtao.github.io/2017/08/20/History-API-and-Location-Object/

【4】https://developer.mozilla.org/zh-CN/docs/Web/API/History

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苦银,一起剝皮案震驚了整個濱河市啸胧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幔虏,老刑警劉巖纺念,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異所计,居然都是意外死亡柠辞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門主胧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叭首,“玉大人,你說我怎么就攤上這事踪栋”焊瘢” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵夷都,是天一觀的道長眷唉。 經(jīng)常有香客問我,道長囤官,這世上最難降的妖魔是什么冬阳? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮党饮,結(jié)果婚禮上肝陪,老公的妹妹穿的比我還像新娘。我一直安慰自己刑顺,他們只是感情好氯窍,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布饲常。 她就那樣靜靜地躺著,像睡著了一般狼讨。 火紅的嫁衣襯著肌膚如雪贝淤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天政供,我揣著相機(jī)與錄音播聪,去河邊找鬼。 笑死鲫骗,一個胖子當(dāng)著我的面吹牛犬耻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播执泰,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼渡蜻!你這毒婦竟也來了术吝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤茸苇,失蹤者是張志新(化名)和其女友劉穎排苍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體学密,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡淘衙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腻暮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彤守。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哭靖,靈堂內(nèi)的尸體忽然破棺而出具垫,到底是詐尸還是另有隱情,我是刑警寧澤试幽,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布筝蚕,位于F島的核電站,受9級特大地震影響铺坞,放射性物質(zhì)發(fā)生泄漏起宽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一济榨、第九天 我趴在偏房一處隱蔽的房頂上張望坯沪。 院中可真熱鬧,春花似錦腿短、人聲如沸屏箍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赴魁。三九已至卸奉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間颖御,已是汗流浹背榄棵。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留潘拱,地道東北人疹鳄。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像芦岂,于是被迫代替她去往敵國和親瘪弓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容