摘要:首發(fā)前端路由實(shí)現(xiàn)了解新增了兩個(gè)和兩個(gè)都接收三個(gè)參數(shù)狀態(tài)對(duì)象一個(gè)對(duì)象,與用方法創(chuàng)建的新歷史記錄條目關(guān)聯(lián)。考慮到未來(lái)可能會(huì)對(duì)該方法進(jìn)行修改,傳一個(gè)空字符串會(huì)比較安全。該參數(shù)是可選的不指定的話則為文檔當(dāng)前。
首發(fā):前端路由實(shí)現(xiàn)(history)
了解HTML5 history新增了兩個(gè)API:history.pushState和history.replaceState
兩個(gè)API都接收三個(gè)參數(shù):
狀態(tài)對(duì)象(state object):一個(gè)JavaScript對(duì)象,與用pushState()方法創(chuàng)建的新歷史記錄條目關(guān)聯(lián)。無(wú)論何時(shí)用戶導(dǎo)航到新創(chuàng)建的狀態(tài),popstate事件都會(huì)被觸發(fā),并且事件對(duì)象的state屬性都包含歷史記錄條目的狀態(tài)對(duì)象的拷貝。
標(biāo)題(title):FireFox瀏覽器目前會(huì)忽略該參數(shù),雖然以后可能會(huì)用上。考慮到未來(lái)可能會(huì)對(duì)該方法進(jìn)行修改,傳一個(gè)空字符串會(huì)比較安全。或者,你也可以傳入一個(gè)簡(jiǎn)短的標(biāo)題,標(biāo)明將要進(jìn)入的狀態(tài)。
地址(URL): 新的歷史記錄條目的地址。瀏覽器不會(huì)在調(diào)用pushState()方法后加載該地址,但之后,可能會(huì)試圖加載,例如用戶重啟瀏覽器。新的URL不一定是絕對(duì)路徑;如果是相對(duì)路徑,它將以當(dāng)前URL為基準(zhǔn);傳入的URL與當(dāng)前URL應(yīng)該是同源的,否則,pushState()會(huì)拋出異常。該參數(shù)是可選的;不指定的話則為文檔當(dāng)前URL。
相同之處是兩個(gè) API 都會(huì)操作瀏覽器的歷史記錄,而不會(huì)引起頁(yè)面的刷新。
不同之處在于pushState會(huì)增加一條新的歷史記錄,而replaceState則會(huì)替換當(dāng)前的歷史記錄。
這里大家可以先F12試試,看看地址欄發(fā)生了什么變化
window.history.pushState(null, null, "hell"); window.history.pushState(null, null, "/hell"); window.history.pushState(null, null, "#/hello"); window.history.pushState(null, null, "?name=");
注意:這里的url不支持跨域,否則會(huì)拋出異常嘗試
index.html
前端路由實(shí)現(xiàn)
router.js
;(function(){ history.replaceState(null,null,"");//最開(kāi)始的狀態(tài),采用replace直接替換 $("#router").html("nav1
") $("a").on("click",function(){ console.log(this.text) var text = this.text; $("#router").html(""+ text +"
") history.pushState(null,null,"#/"+text); }) })()
最簡(jiǎn)單的示例,只能監(jiān)聽(tīng)點(diǎn)擊事件,而瀏覽器中的后、前進(jìn)都不能監(jiān)聽(tīng)地址欄的改變
router.js
狀態(tài)版 ;(function(){ var count = [0,0,0] $("#router").html("導(dǎo)航1:
"+count[0]+"導(dǎo)航2:
"+count[1]+"導(dǎo)航3:
"+count[2]) history.replaceState(count,null,"");//最開(kāi)始的狀態(tài),采用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("導(dǎo)航1:
"+count[0]+"導(dǎo)航2:
"+count[1]+"導(dǎo)航3:
"+count[2]) history.pushState(count,null,"#/count"+count[index]);//之后的狀態(tài),需要進(jìn)行保存 }) } //監(jiān)聽(tīng)history其他api導(dǎo)致地址欄url改變事件 window.addEventListener("popstate",function(e){ console.log(e.state); var state = e.state; $("#router").html("導(dǎo)航1:
"+state[0]+"導(dǎo)航2:
"+state[1]+"導(dǎo)航3:
"+state[2]) }) })()
popstate
當(dāng)活動(dòng)歷史記錄條目更改時(shí),將觸發(fā)popstate事件。如果被激活的歷史記錄條目是通過(guò)對(duì)history.pushState()的調(diào)用創(chuàng)建的,或者受到對(duì)history.replaceState()的調(diào)用的影響,popstate事件的state屬性包含歷史條目的狀態(tài)對(duì)象的副本。需要注意的是調(diào)用history.pushState()或history.replaceState()不會(huì)觸發(fā)popstate事件。只有在做出瀏覽器動(dòng)作時(shí),才會(huì)觸發(fā)該事件,如用戶點(diǎn)擊瀏覽器的回退按鈕(或者在Javascript代碼中調(diào)用history.back())
router.js
;(function(){ var url = "nav1"; history.replaceState(url,null,"");//最開(kāi)始的狀態(tài),采用replace直接替換 $("#router").html(""+url+"
") $("a").on("click",function(){ console.log(this.text) url = this.text; $("#router").html(""+ url +"
") history.pushState(url,null,"#/"+url); }) window.addEventListener("popstate",function(e){ console.log(e.state); url = e.state $("#router").html(""+ url +"
") }); })()
兜兜轉(zhuǎn)轉(zhuǎn)我們算是回到了起點(diǎn),但是通過(guò)這張圖我們會(huì)發(fā)現(xiàn)頁(yè)面點(diǎn)擊刷新按鈕會(huì)有導(dǎo)航和內(nèi)容塊不一致的內(nèi)容,所以我們需要改進(jìn)他,并且監(jiān)聽(tīng)load事件
改進(jìn)
;(function(){ $("a").on("click",function(){ console.log(this.text) url = this.text; $("#router").html(""+ url +"
") history.pushState(url,null,"#/"+url); }) window.addEventListener("popstate",function(e){ console.log(e.state); url = e.state $("#router").html(""+ url +"
") }); window.addEventListener("load",function(){ url = location.hash.slice(2) || "nav1"; history.replaceState(url,null,""); console.log(location.hash); $("#router").html(""+ url +"
"); }); })()
可以看到我們點(diǎn)擊刷新的時(shí)候?qū)Ш胶蛢?nèi)容區(qū)域一致了。
我們這里還是采用了ajax的load方法
router.js
;(function(){ var router = [ { "path":"index", "url":"./main.html" }, { "path":"news", "url":"./news.html" }, { "path":"about", "url":"./about.html" } ]; //改變頁(yè)面 function display_page(url){ $("#router").load(url) } $("a").on("click",function(){ var path = $(this).data("path"); console.log(path) for(var i in router){ if(router[i].path == path){ display_page(router[i].url); history.pushState(router[i].url,null,router[i].path); } } }) window.addEventListener("popstate",function(e){ var url = e.state; display_page(url); }); window.addEventListener("load",function(){ var start = location.href.lastIndexOf("/"); var path = location.hash.slice(start) || "index"; console.log(path) for(var i in router){//刷新 加載 console.log(1) if(router[i].path == path){ display_page(router[i].url); history.replaceState(router[i].url,null,path); break; } if(i == router.length-1){//重定向 display_page(router[0].url); history.replaceState(router[i].url,null,router[0].path); } } }); })()
可以看到基本是實(shí)現(xiàn)了history路由功能,但是這里有一個(gè)問(wèn)題就是刷新后因?yàn)榈刂窓趗rl原因會(huì)報(bào)錯(cuò),也就是找不到這個(gè)頁(yè)面,這是由于刷新的時(shí)候是重載,重新向網(wǎng)站目錄查找文件,而我們當(dāng)前目錄并沒(méi)有這個(gè)文件資源所以導(dǎo)致報(bào)錯(cuò)。需要后臺(tái)攔截! 放棄!
折中
最后我還是屈服于#了
;(function(){ var router = [ { "path":"index", "url":"./main.html" }, { "path":"news", "url":"./news.html" }, { "path":"about", "url":"./about.html" } ]; //改變頁(yè)面 function display_page(url){ $("#router").load(url) } $("a").on("click",function(){ var path = $(this).data("path"); console.log(path) for(var i in router){ if(router[i].path == path){ display_page(router[i].url); history.pushState(router[i].url,null,"#/"+router[i].path); } } }) window.addEventListener("popstate",function(e){ var url = e.state; display_page(url); }); window.addEventListener("load",function(){ var path = location.hash.slice(2) || "/index"; console.log(path) for(var i in router){//刷新 加載 console.log(1) if(router[i].path == path){ display_page(router[i].url); history.replaceState(router[i].url,null,"#/" + path); break; } if(i == router.length-1){//重定向 display_page(router[0].url); history.replaceState(router[0].url,null,"#/" + router[0].path); } } }); })();
勉強(qiáng)的很呀
代碼: router(history)
演示: 演示地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/95584.html
摘要:而應(yīng)用便是基于前端路由實(shí)現(xiàn)的所以便有了前端路由。因?yàn)閮煞N模式都需要調(diào)用一個(gè)方法來(lái)實(shí)現(xiàn)不同路由內(nèi)容的刷新前端路由路由列表匹配當(dāng)前的路由匹配不到則使用配置內(nèi)容并渲染下面我們來(lái)實(shí)現(xiàn)兩種模式。 什么是路由? 路由這概念最開(kāi)始是在后端出現(xiàn)的,在以前前后端不分離的時(shí)候,由后端來(lái)控制路由,服務(wù)器接收客戶端的請(qǐng)求,解析對(duì)應(yīng)的url路徑,并返回對(duì)應(yīng)的頁(yè)面/資源。 簡(jiǎn)單的說(shuō) 路由就是根據(jù)不同的url地...
摘要:如何實(shí)現(xiàn)前端路由要實(shí)現(xiàn)前端路由,需要解決兩個(gè)核心如何改變卻不引起頁(yè)面刷新如何檢測(cè)變化了下面分別使用和兩種實(shí)現(xiàn)方式回答上面的兩個(gè)核心問(wèn)題。 原文鏈接:github.com/whinc/blog/… 在單頁(yè)應(yīng)用如此流行的今天,曾經(jīng)令人驚嘆的前端路由已經(jīng)成為各大框架的基礎(chǔ)標(biāo)配,每個(gè)框架都提供了強(qiáng)大的路由功能,導(dǎo)致路由實(shí)現(xiàn)變的復(fù)雜。想要搞懂路由內(nèi)部實(shí)現(xiàn)還是有些困難的,但是如果只想了解路由實(shí)現(xiàn)基本...
摘要:回調(diào)函數(shù)將在更新時(shí)觸發(fā),回調(diào)中的起到了新的的作用。注冊(cè)回調(diào)在中使用注冊(cè)的回調(diào)函數(shù),最終放在模塊的回調(diào)函數(shù)數(shù)組中。 原文地址:https://github.com/joeyguo/blog/issues/2 在單頁(yè)應(yīng)用上,前端路由并不陌生。很多前端框架也會(huì)有獨(dú)立開(kāi)發(fā)或推薦配套使用的路由系統(tǒng)。那么,當(dāng)我們?cè)谡勄岸寺酚傻臅r(shí)候,還可以談些什么?本文將簡(jiǎn)要分析并實(shí)現(xiàn)一個(gè)的前端路由,并對(duì) reac...
摘要:?jiǎn)雾?yè)面應(yīng)用利用了動(dòng)態(tài)變換網(wǎng)頁(yè)內(nèi)容避免了頁(yè)面重載路由則提供了瀏覽器地址變化網(wǎng)頁(yè)內(nèi)容也跟隨變化兩者結(jié)合起來(lái)則為我們提供了體驗(yàn)良好的單頁(yè)面應(yīng)用前端路由實(shí)現(xiàn)方式路由需要實(shí)現(xiàn)三個(gè)功能瀏覽器地址變化切換頁(yè)面點(diǎn)擊瀏覽器后退前進(jìn)按鈕,網(wǎng)頁(yè)內(nèi)容跟隨變化刷新瀏 單頁(yè)面應(yīng)用利用了JavaScript動(dòng)態(tài)變換網(wǎng)頁(yè)內(nèi)容,避免了頁(yè)面重載;路由則提供了瀏覽器地址變化,網(wǎng)頁(yè)內(nèi)容也跟隨變化,兩者結(jié)合起來(lái)則為我們提供了體...
摘要:開(kāi)發(fā)中路由實(shí)現(xiàn)原理開(kāi)發(fā)中路由實(shí)現(xiàn)原理服務(wù)端路由路由前端路由實(shí)現(xiàn)比較參考什么是路由根據(jù)不同的地址,展示不同的頁(yè)面或者更新頁(yè)面局部視圖服務(wù)端路由服務(wù)器端路由管理,常見(jiàn)的開(kāi)發(fā)模式是前端根據(jù)的不同,使用發(fā)起異步請(qǐng)求,獲取不同的頁(yè)面資源,前端獲取資源 Web開(kāi)發(fā)中路由實(shí)現(xiàn)原理 Web開(kāi)發(fā)中路由實(shí)現(xiàn)原理 服務(wù)端路由 Hash路由 History 前端路由實(shí)現(xiàn)比較 參考: 什么是路由: 根據(jù)不同...
閱讀 2861·2021-10-14 09:50
閱讀 1218·2021-10-08 10:21
閱讀 3646·2021-10-08 10:16
閱讀 3063·2021-09-27 14:02
閱讀 3135·2021-09-23 11:21
閱讀 2109·2021-09-07 10:17
閱讀 407·2019-08-30 14:00
閱讀 2105·2019-08-29 17:26