路由模式: hash模式和history

前端路由實(shí)現(xiàn)方式

路由需要實(shí)現(xiàn)三個(gè)功能:

  1. 當(dāng)瀏覽器地址變化時(shí)市咆, 切換頁(yè)面秤掌。
  2. 點(diǎn)擊瀏覽器后退愁铺、前進(jìn)按鈕,網(wǎng)頁(yè)內(nèi)容跟隨變化闻鉴。
  3. 刷新瀏覽器茵乱, 網(wǎng)頁(yè)加載當(dāng)前路由對(duì)應(yīng)內(nèi)容。

在單頁(yè)面web網(wǎng)頁(yè)中孟岛,單純的瀏覽器地址改變瓶竭,網(wǎng)頁(yè)不會(huì)重載, 如值改變hash網(wǎng)頁(yè)不會(huì)變化渠羞, 因此路由主要通過監(jiān)聽事件斤贰, 并利用js實(shí)現(xiàn)動(dòng)態(tài)改變網(wǎng)頁(yè)內(nèi)容, 有兩種實(shí)現(xiàn)方式:

  • hash模式: 監(jiān)聽瀏覽器地址hash值變化次询, 執(zhí)行響應(yīng)js切換網(wǎng)頁(yè)荧恍。
  • history模式: 利用history API實(shí)現(xiàn)url地址改變, 網(wǎng)頁(yè)內(nèi)容改變屯吊。
    他們的區(qū)別最明顯的就是 hash API會(huì)在瀏覽器后面增加 #號(hào)送巡, 而history可以自定義地址。

hash模式

使用window.localtion.hash屬性及窗口的onhashchange事件盒卸, 可以實(shí)現(xiàn)監(jiān)聽瀏覽器地址hash值變化骗爆, 執(zhí)行相應(yīng)js切換頁(yè)面。

  1. hash 指的是地址中 #號(hào)以及后面的字符蔽介, 也成為散列值摘投。hash也稱作錨點(diǎn), 本身是用來做頁(yè)面跳轉(zhuǎn)定位的虹蓄。如 http://localhost/index.html#name犀呼,這里的#name就是hash;
  2. 散列值是不會(huì)隨請(qǐng)求發(fā)送到服務(wù)器端的武花, 所以改變hash不會(huì)重新加載頁(yè)面圆凰。
  3. 監(jiān)聽 window的hashchange事件,當(dāng)hash值發(fā)生變化時(shí)体箕, 可以通過location.hash來獲取和設(shè)置hash值专钉。
  4. location.hash值的變化會(huì)直接反應(yīng)到瀏覽器地址欄挑童。

觸發(fā)hashchange事件的幾種情況:

  • 瀏覽器地址欄hash的變化包括瀏覽器的前進(jìn)、后退跃须,會(huì)觸發(fā)window.location.hash值的變化站叼, 從而觸發(fā)onhashchange事件。
  • 當(dāng)訪問http://localhost/index.html#name只會(huì)向服務(wù)器發(fā)送 http://localhost/index.html菇民,請(qǐng)求完畢之后設(shè)置hash為#name, 并觸發(fā)onhashchange事件尽楔。
  • 當(dāng)只改變地址欄url 的hash部分, 按下回車第练, 瀏覽器不會(huì)發(fā)送任何請(qǐng)求至服務(wù)器阔馋, 這是只改動(dòng)了hash值并觸發(fā)onhashchange事件。
  • html中a標(biāo)簽通過ID定位錨點(diǎn)娇掏, 同時(shí)urL會(huì)自動(dòng)設(shè)置hash呕寝,并觸發(fā)onhashchange事件。
//改變hash
 window.location.hash = 'name';
//監(jiān)聽hashchange
  window.addEventListener('hashchange', function (e) {
    console.log(e);
  });

history模式

History對(duì)象主要有兩個(gè)屬性婴梧。

  • History.length (當(dāng)前窗口訪問過的網(wǎng)址數(shù)量下梢,包括當(dāng)前網(wǎng)頁(yè))
  • History.state (History堆棧最上層的狀態(tài)值)
history.length;
history.state;

方法

  • History,back():移動(dòng)到上一個(gè)網(wǎng)址,等同于點(diǎn)擊瀏覽器后退鍵塞蹭。對(duì)于第一個(gè)訪問的網(wǎng)址孽江,該方法無效。
  • History.forward(): 移動(dòng)到下一個(gè)網(wǎng)站番电, 等同于瀏覽器的后退鍵岗屏。 對(duì)于最后一個(gè)訪問的網(wǎng)址,該方法無效钧舌。
    History.go(): 接受一個(gè)整數(shù)作為參數(shù)担汤, 以當(dāng)前網(wǎng)址為基準(zhǔn)涎跨, 默認(rèn)參數(shù)為0洼冻, 相當(dāng)于刷新頁(yè)面。
history.back();
history.forward();
history.go(1);  // 相當(dāng)于history.forward();
histroy.go(-1); //相當(dāng)于history.back();
history.go(0); //刷新當(dāng)前頁(yè)

注意: 移動(dòng)到以前訪問過的頁(yè)面時(shí)隅很, 頁(yè)面通常是從瀏覽器緩中加載撞牢, 而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁(yè)。
History.pushState()
該方法用于在歷史中添加一條記錄叔营。 pushState()方法不會(huì)觸發(fā)頁(yè)面刷新屋彪, 只是導(dǎo)致History對(duì)象發(fā)生變化, 地址欄會(huì)有變化绒尊。
語法: history.push(object, title, url);

  • object: 通過pushState方法可以將該對(duì)象傳遞到新的頁(yè)面中畜挥。 不需要可以填null。
  • title: 標(biāo)題婴谱, string蟹但,目前幾乎沒有瀏覽器支持該參數(shù)躯泰,,可以填空字符串华糖。
  • url: 新的網(wǎng)址麦向, 必須與當(dāng)前頁(yè)面處在同一個(gè)域。 如果是跨域網(wǎng)址則會(huì)報(bào)錯(cuò)(這么設(shè)計(jì)是為了防止惡意代碼讓用戶以為他們是在另一個(gè)網(wǎng)站上)客叉。
var data = {name: 'data'};
history.pushState(data,' ','/open');
console.log(history.state);// {name: 'data'}

注意: 如果pushState的url參數(shù)設(shè)置了一個(gè)新的hash诵竭, 并不會(huì)觸發(fā)hashchange事件。反過來兼搏, 如果url的hash變動(dòng)了卵慰,則會(huì)在History對(duì)象創(chuàng)建一條瀏覽記錄。

HIstory.replaceState()
該方法用來修改History對(duì)象的當(dāng)前記錄佛呻, 用法與pushState()方法一樣

history.pushState({a: 1}, ' ', '?a=1');
//url為  https://www.baidu.com?a=1

history.pushState({a: 2}, ' ', '?a=2');
//url為  https://www.baidu.com?a=2

history.pushState({a: 3}, ' ', '?a=3');
//url為  https://www.baidu.com?a=3

history.back();
//url為  https://www.baidu.com?a=1

history.back();
 //url為 https://www.baidu.com

history.go(2);
//url為  https://www.baidu.com?a=3

popstate事件
每當(dāng)history度歘愛能出現(xiàn)變化時(shí)呵燕, 就會(huì)觸發(fā)popstate事件。

  • 僅僅調(diào)用pushState()replaceState()方法件相, 并不會(huì)觸發(fā)popstate事件再扭。
  • 只有點(diǎn)擊瀏覽器前進(jìn)倒退按鈕,或者使用js調(diào)用history,back(),history.forward(),history.go()方法時(shí)才會(huì)觸發(fā)夜矗。
  • popstate事件只針對(duì)同一個(gè)文檔泛范, 如果瀏覽歷史的切換, 導(dǎo)致加載不同的文檔紊撕, 該事件也不會(huì)觸發(fā)罢荡。
  • 頁(yè)面第一次加載的時(shí)候, 瀏覽器不會(huì)觸發(fā)popstate事件对扶。
window.addEventListener('popstate',function(e) {
  var s1 = e.state;
  var s2 = history.state;
  // s1 == s2
});

history致命的缺點(diǎn)是當(dāng)改變頁(yè)面地址后区赵,強(qiáng)制刷新瀏覽器時(shí), 如果后端沒有對(duì)應(yīng)的地址浪南,會(huì)404笼才,因?yàn)樗⑿率悄卯?dāng)前地址去請(qǐng)求服務(wù)器, 如果服務(wù)器沒有相應(yīng)的響應(yīng)络凿,頁(yè)面則會(huì)404骡送。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市絮记,隨后出現(xiàn)的幾起案子摔踱,更是在濱河造成了極大的恐慌,老刑警劉巖怨愤,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件派敷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)篮愉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門般眉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人潜支,你說我怎么就攤上這事甸赃。” “怎么了冗酿?”我有些...
    開封第一講書人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵埠对,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我裁替,道長(zhǎng)项玛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任弱判,我火速辦了婚禮襟沮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘昌腰。我一直安慰自己开伏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開白布遭商。 她就那樣靜靜地躺著固灵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劫流。 梳的紋絲不亂的頭發(fā)上巫玻,一...
    開封第一講書人閱讀 52,793評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音祠汇,去河邊找鬼仍秤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛可很,可吹牛的內(nèi)容都是我干的诗力。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼根穷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼姜骡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屿良,我...
    開封第一講書人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惫周,沒想到半個(gè)月后尘惧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡递递,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年喷橙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啥么。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贰逾,死狀恐怖悬荣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疙剑,我是刑警寧澤氯迂,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站言缤,受9級(jí)特大地震影響嚼蚀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜管挟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一轿曙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧僻孝,春花似錦导帝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悴务,卻和暖如春睹限,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讯檐。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工羡疗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人别洪。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓叨恨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親挖垛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痒钝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361

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