摘要:這里借鑒了一下的處理方式,我們把多帶帶模塊的包裝成一個(gè)函數(shù),提供一個(gè)全局的回調(diào)方法,加載完成時(shí)候再調(diào)用回調(diào)函數(shù)。
前端路由實(shí)現(xiàn)之 #hash
先上github項(xiàng)目地址: spa-routers
運(yùn)行效果圖
用了許多前端框架來(lái)做spa應(yīng)用,比如說(shuō)backbone,angular,vue他們都有各自的路由系統(tǒng),管理著前端的每一個(gè)頁(yè)面切換,想要理解其中路由的實(shí)現(xiàn),最好的方法就是手動(dòng)實(shí)現(xiàn)一個(gè)。
前端路由有2種實(shí)現(xiàn)方式,一種是html5推出的historyapi,我們這里說(shuō)的是另一種hash路由,就是常見(jiàn)的 # 號(hào),這種方式兼容性更好。
我們這里只是簡(jiǎn)單的實(shí)現(xiàn)一個(gè)路由輪子,基本的功能包含以下:
切換頁(yè)面
異步加載js
異步傳參
實(shí)現(xiàn)步驟
切換頁(yè)面:路由的最大作用就是切換頁(yè)面,以往后臺(tái)的路由是直接改變了頁(yè)面的url方式促使頁(yè)面刷新。但是前端路由通過(guò) # 號(hào)不能刷新頁(yè)面,只能通過(guò) window 的監(jiān)聽(tīng)事件 hashchange 來(lái)監(jiān)聽(tīng)hash的變化,然后捕獲到具體的hash值進(jìn)行操作
//路由切換 window.addEventListener("hashchange",function(){ //do something this.hashChange() })
注冊(cè)路由:我們需要把路由規(guī)則注冊(cè)到頁(yè)面,這樣頁(yè)面在切換的時(shí)候才會(huì)有不同的效果。
//注冊(cè)函數(shù) map:function(path,callback){ path = path.replace(/s*/g,"");//過(guò)濾空格 //在有回調(diào),且回調(diào)是一個(gè)正確的函數(shù)的情況下進(jìn)行存儲(chǔ) 以 /name 為key的對(duì)象 {callback:xx} if(callback && Object.prototype.toString.call(callback) === "[object Function]" ){ this.routers[path] ={ callback:callback,//回調(diào) fn:null //存儲(chǔ)異步文件狀態(tài),用來(lái)記錄異步的js文件是否下載,下文有提及 } }else{ //打印出錯(cuò)的堆棧信息 console.trace("注冊(cè)"+path+"地址需要提供正確的的注冊(cè)回調(diào)") } } //調(diào)用方式 map("/detail",function(transition){ ... })
異步加載js:一般單頁(yè)面應(yīng)用為了性能優(yōu)化,都會(huì)把各個(gè)頁(yè)面的文件拆分開(kāi),按需加載,所以路由里面要加入異步加載js文件的功能。異步加載我們就采用最簡(jiǎn)單的原生方法,創(chuàng)建script標(biāo)簽,動(dòng)態(tài)引入js。
var _body= document.getElementsByTagName("body")[0], scriptEle= document.createElement("script"); scriptEle.type= "text/javascript"; scriptEle.src= xxx.js; scriptEle.async = true; scriptEle.onload= function(callback){ //為了避免重復(fù)引入js,我們需要在這里記錄一下已經(jīng)加載過(guò)的文件,對(duì)應(yīng)的 fn需要賦值處理 callback() } _body.appendChild(scriptEle);
參數(shù)傳遞:在我們動(dòng)態(tài)引入多帶帶模塊的js之后,我們可能需要給這個(gè)模塊傳遞一些多帶帶的參數(shù)。這里借鑒了一下jsonp的處理方式,我們把多帶帶模塊的js包裝成一個(gè)函數(shù),提供一個(gè)全局的回調(diào)方法,加載完成時(shí)候再調(diào)用回調(diào)函數(shù)。
SPA_RESOLVE_INIT = function(transition) { document.getElementById("content").innerHTML = "當(dāng)前異步渲染列表頁(yè)"+ JSON.stringify(transition) +"
" console.log("首頁(yè)回調(diào)" + JSON.stringify(transition)) }
擴(kuò)展:以上我們已經(jīng)完成了基本功能,我們?cè)賹?duì)齊進(jìn)行擴(kuò)展,在頁(yè)面切換之前beforeEach和切換完成afterEach的時(shí)候增加2個(gè)方法進(jìn)行處理。思路是,注冊(cè)了這2個(gè)方法之后,在切換之前就調(diào)用beforeEach,切換之后,需要等待下載js完成,在onload里面進(jìn)行調(diào)用 afterEach
//切換之前一些處理 beforeEach:function(callback){ if(Object.prototype.toString.call(callback) === "[object Function]"){ this.beforeFun = callback; }else{ console.trace("路由切換前鉤子函數(shù)不正確") } }, //切換成功之后 afterEach:function(callback){ if(Object.prototype.toString.call(callback) === "[object Function]"){ this.afterFun = callback; }else{ console.trace("路由切換后回調(diào)函數(shù)不正確") } },
通過(guò)以上的思路分析,再加以整合,我們就完成了一個(gè)簡(jiǎn)單的前端路由,并且可以加到頁(yè)面進(jìn)行實(shí)際的SPA開(kāi)發(fā),不過(guò)還是非常簡(jiǎn)陋。
完整代碼/* *author:https://github.com/kliuj **使用方法 * 1:注冊(cè)路由 : spaRouters.map("/name",function(transition){ //異步加載js spaRouters.asyncFun("name.js",transition) //或者同步執(zhí)行回調(diào) spaRouters.syncFun(function(transition){},transition) }) 2:初始化 spaRouters.init() 3:跳轉(zhuǎn) href = "#/name" */ (function() { var util = { //獲取路由的路徑和詳細(xì)參數(shù) getParamsUrl:function(){ var hashDeatail = location.hash.split("?"), hashName = hashDeatail[0].split("#")[1],//路由地址 params = hashDeatail[1] ? hashDeatail[1].split("&") : [],//參數(shù)內(nèi)容 query = {}; for(var i = 0;i簡(jiǎn)單的單頁(yè)面在github上有完整的demo
spa-routers以上僅是我個(gè)人的一些看法,如有疑問(wèn),感謝指導(dǎo)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80805.html
摘要:原作者原鏈接基于多入口生成模板用于服務(wù)端渲染的方案及實(shí)戰(zhàn)法律聲明警告本作品遵循署名非商業(yè)性使用禁止演繹未本地化版本協(xié)議發(fā)布。這是什么背景現(xiàn)代化的前端項(xiàng)目中很多都使用了客戶(hù)端渲染的單頁(yè)面應(yīng)用。 原作者:@LinuxerPHL原鏈接:基于 Webpack 4 多入口生成模板用于服務(wù)端渲染的方案及實(shí)戰(zhàn) 法律聲明 警告:本作品遵循 署名-非商業(yè)性使用-禁止演繹3.0 未本地化版本(CC BY-...
摘要:原作者原博文地址基于多入口生成模板用于服務(wù)端渲染的方案及實(shí)戰(zhàn)法律聲明警告本作品遵循署名非商業(yè)性使用禁止演繹未本地化版本協(xié)議發(fā)布。這是什么背景現(xiàn)代化的前端項(xiàng)目中很多都使用了客戶(hù)端渲染的單頁(yè)面應(yīng)用。 原作者:@LinuxerPHL原博文地址: 基于 Webpack 4 多入口生成模板用于服務(wù)端渲染的方案及實(shí)戰(zhàn) 法律聲明 警告:本作品遵循 署名-非商業(yè)性使用-禁止演繹3.0 未本地化版本(...
摘要:后續(xù)我們還會(huì)增加一些實(shí)戰(zhàn)類(lèi)的移動(dòng)開(kāi)發(fā)案例,歡迎關(guān)注專(zhuān)欄。進(jìn)入官網(wǎng)新版預(yù)覽在線預(yù)覽需要使用開(kāi)啟設(shè)備模擬,效果更佳。 前言 之前寫(xiě)過(guò)一篇 2018開(kāi)發(fā)最快的Webapp框架--BUI交互框架 ,如果你還沒(méi)看過(guò),可以簡(jiǎn)單看一下,主要介紹了BUI的基本功能,有多少控件,以及實(shí)現(xiàn)的思路,BUI 1.5版本以后變化很大,統(tǒng)一新的風(fēng)格,新的規(guī)范750,新增基于Dom的數(shù)據(jù)驅(qū)動(dòng),完善了頁(yè)面的生命周期等...
摘要:?jiǎn)雾?yè)面應(yīng)用的出現(xiàn)依然存在著爭(zhēng)議性,我們?cè)撊绾慰创膬擅嫘阅亟酉聛?lái)小生給大家總結(jié)一下他的優(yōu)缺點(diǎn)。單頁(yè)面應(yīng)用的優(yōu)勢(shì)無(wú)刷新體驗(yàn)沒(méi)有了令人詬病的頁(yè)面頻繁刷新,同時(shí)節(jié)約瀏覽器資源,路由響應(yīng)比較及時(shí),提升了用戶(hù)的體驗(yàn)。 前端猿一天不學(xué)習(xí)就沒(méi)飯吃了,后端猿三天不學(xué)習(xí)仍舊有白米飯擺于桌前。IT行業(yè)的快速發(fā)展一直在推動(dòng)著前端技術(shù)棧在不斷地更新?lián)Q代,前端的發(fā)展成了互聯(lián)網(wǎng)時(shí)代的一個(gè)縮影。而單頁(yè)面應(yīng)用的發(fā)展...
閱讀 2782·2021-10-26 09:50
閱讀 2424·2021-10-11 11:08
閱讀 2165·2019-08-30 15:53
閱讀 1929·2019-08-30 15:44
閱讀 2413·2019-08-28 18:12
閱讀 2558·2019-08-26 13:59
閱讀 2881·2019-08-26 12:19
閱讀 2789·2019-08-26 12:09