日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端路由实现原理(history)

發布時間:2023/12/2 HTML 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端路由实现原理(history) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前端路由實現(history)

了解:

HTML5 history新增了兩個API:history.pushState和history.replaceState

兩個api都接受三個參數

  • 狀態對象(state object):一個JavaScript對象,與用pushState()方法創建的新歷史記錄條目關聯。無論何時用戶導航到新創建的狀態,popstate事件都會被觸發,并且事件對象的state屬性都包含歷史記錄條目的狀態對象的拷貝。

  • 標題(title):FireFox瀏覽器目前會忽略該參數,雖然以后可能會用上。考慮到未來可能會對該方法進行修改,傳一個空字符串會比較安全。或者,你也可以傳入一個簡短的標題,標明將要進入的狀態。

  • 地址(URL): 新的歷史記錄條目的地址。瀏覽器不會在調用pushState()方法后加載該地址,但之后,可能會試圖加載,例如用戶重啟瀏覽器。新的URL不一定是絕對路徑;如果是相對路徑,它將以當前URL為基準;傳入的URL與當前URL應該是同源的,否則,pushState()會拋出異常。該參數是可選的;不指定的話則為文檔當前URL。

相同之處是兩個API都會操作瀏覽器的歷史記錄,而不會引起頁面的刷新。不同之處在于pushState會增加一條新的歷史記錄,而replaceState則會替換當前的歷史記錄

大家可以先在控制臺試試,看看地址欄發生了什么變化

window.history.pushState(null, null, "test");window.history.pushState(null, null, "/test");window.history.pushState(null, null, "#/hello");window.history.pushState(null, null, "?name="); </code></pre>

實例演示

建立html文件,index.html

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>前端路由實現</title><style>.warp{width:400px;height:400px;border:1px solid grey;margin:0 auto;}.nav{border-bottom:1px solid grey;}.nav li{display:inline-block;list-style:none;}.nav li a{display:inline-block;text-decoration: none;padding:10px 15px;}.router{padding:20px;}a{cursor: pointer;}</style></head> <body><section class="warp"><div class="nav"> <ul><li><a href="javascript:void(0)" data-path="index">首頁</a></li> <li><a href="javascript:void(0)" data-path="news">新聞</a></li><li><a href="javascript:void(0)" data-path="about">關于</a></li></ul></div><div id="router" class="router"><!-- 內容加載區域 --></div></section><script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script><script src="./router.js"></script></body> </html>

此時的頁面為:

引入js文件router.js

(function(){ history.replaceState(null,null,'');//最開始的狀態,采用replace直接替換$('#router').html('<p>顯示內容區域</p>')$('a').on('click',function(){console.log(this.text)var text = this.text;$('#router').html('<p>' text '</p>')history.pushState(null,null,'#/' text);}) })()

此時點擊導航按鈕時

  • 此時當點擊不同的導航項的時候,地址欄上的路由進行了對應的改變,展現的內容區域也發生了變化。但是實際上這個并沒有實現路由的真正含義。因為內容部分的改變是根據事件的觸發而獲得當前的內容。
  • 此時如果點擊瀏覽的前進和后退按鈕,內容是無法監聽到地址欄的變化而作出改變的

在此基礎上變動一下實現方式,將router.js改為:

// 狀態版 (function(){ var count = [0,0,0]$('#router').html('<p>首頁</p>' count[0] '<p>新聞</p>' count[1] '<p>關于</p>' count[2])// history.replaceState(count,null,'');//最開始的狀態,采用replace直接替換for(var i = 0 ; i<$('a').length; i ){$('a')[i].index = i$('a').eq(i).on('click',function(){console.log(this.index);var index = this.index;count[index] ;$('#router').html('<p>首頁</p>' count[0] '<p>新聞</p>' count[1] '<p>關于</p>' count[2])console.log(count)history.pushState(count,null,'#/count' count[index]);//之后的狀態,需要進行保存})}//監聽history其他api導致地址欄url改變事件window.addEventListener('popstate',function(e){console.log(e.state);var state = e.state;$('#router').html('<p>首頁</p>' state[0] '<p>新聞</p>' state[1] '<p>關于</p>' state[2])}) })()

此時的思路是做一個狀態記錄,記錄下每個導航按鈕被點擊的次數。當每次執行點擊導航欄切換的時候,通過history.pushState(count, null, '#/count' count[index])這個api,傳遞了狀態對象在內,并在第三個參數中將當前已點擊數作為地址欄的顯示數據。示例如下:

  • !!當活動歷史記錄條目更改時,將觸發popstate事件。如果被激活的歷史記錄條目是通過對history.pushState()的調用創建的,或者受到對history.replaceState()的調用的影響,popstate事件的state屬性包含歷史條目的狀態對象的副本。
  • 需要注意的是調用history.pushState()或history.replaceState()不會觸發popstate事件。只有在做出瀏覽器動作時,才會觸發該事件,如用戶點擊瀏覽器的回退按鈕(或者在Javascript代碼中調用history.back())

此處通過記錄下每次的點擊次數來解釋了pushState的用法以及參數,其實簡單的寫法可以表達為:

(function(){ var url = '內容展示';history.replaceState(url,null,'');//最開始的狀態,采用replace直接替換$('#router').html('<p>' url '</p>')$('a').on('click',function(){console.log(this.text)url = this.text;$('#router').html('<p>' url '</p>')history.pushState(url,null,'#/' url);})window.addEventListener('popstate',function(e){console.log(e.state);url = e.state$('#router').html('<p>' url '</p>')}); })()

現在的效果看上去其實我們相當于回到了遠點,但是解決了無法監聽地址欄的地址變化問題,是通過監聽popstate來作出響應的。

現在還只是看了這一部分的路由實現機制,要通過監聽作出不同的響應。還需要更深入的與hash進行對比。

總結

以上是生活随笔為你收集整理的前端路由实现原理(history)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。