自行封裝js實現單頁功能


話不多說,先奉上代碼,再慢慢細聊!

/****author: XYB****/

(function() {
var util = {
//獲取路由的路徑和詳細參數
getParamsUrl:function(){
var hashDeatail = location.hash.split("?"),
hashName = hashDeatail[0].split("#")[1],//路由地址
params = hashDeatail[1] ? hashDeatail[1].split("&") : [],//參數內容
query = {};
for(var i = 0;i<params.length ; i++){
var item = params[i].split("=");
query[item[0]] = item[1]
}
return {
path:hashName,
query:query
}
}
}
function spaRouters(){
this.routers = {};//保存注冊的所有路由
this.beforeFun = null;//切換前
this.afterFun = null;
}
spaRouters.prototype={
init:function(){
var self = this;
//頁面加載匹配路由
window.addEventListener('load',function(){
self.urlChange()
})
//路由切換
window.addEventListener('hashchange',function(){
self.urlChange()
})
//異步引入js通過回調傳遞參數
window.SPA_RESOLVE_INIT = null;
},
refresh:function(currentHash){
var self = this;
if(self.beforeFun){
self.beforeFun({
to:{
path:currentHash.path,
query:currentHash.query
},
next:function(){
self.routers[currentHash.path].callback.call(self,currentHash)
}
})
}else{
self.routers[currentHash.path].callback.call(self,currentHash)
}
},
//路由處理
urlChange:function(){
var currentHash = util.getParamsUrl();
if(this.routers[currentHash.path]){
this.refresh(currentHash)
}else{
//不存在的地址重定向到首頁
location.hash = '/index'
}
},
//單層路由注冊
map:function(path,callback){
path = path.replace(/\s*/g,"");//過濾空格
if(callback && Object.prototype.toString.call(callback) === '[object Function]' ){
this.routers[path] ={
callback:callback,//回調
fn:null //存儲異步文件狀態
}
}else{
console.trace('注冊'+path+'地址需要提供正確的的注冊回調')
}
},
//切換之前一些處理
beforeEach:function(callback){
if(Object.prototype.toString.call(callback) === '[object Function]'){
this.beforeFun = callback;
}else{
console.trace('路由切換前鈎子函數不正確')
}
},
//切換成功之后
afterEach:function(callback){
if(Object.prototype.toString.call(callback) === '[object Function]'){
this.afterFun = callback;
}else{
console.trace('路由切換后回調函數不正確')
}
},
//路由異步懶加載js文件
asyncFun:function(file,transition){
var self = this;
if(self.routers[transition.path].fn){
self.afterFun && self.afterFun(transition)
self.routers[transition.path].fn(transition)
}else{
console.log("開始異步下載js文件"+file)
var _body= document.getElementsByTagName('body')[0];
var scriptEle= document.createElement('script');
scriptEle.type= 'text/javascript';
scriptEle.src= file;
scriptEle.async = true;
SPA_RESOLVE_INIT = null;
scriptEle.onload= function(){
console.log('下載'+file+'完成')
self.afterFun && self.afterFun(transition)
self.routers[transition.path].fn = SPA_RESOLVE_INIT;
self.routers[transition.path].fn(transition)
}
_body.appendChild(scriptEle);
}
},
//同步操作
syncFun:function(callback,transition){
this.afterFun && this.afterFun(transition)
callback && callback(transition)
}

}
//注冊到window全局
window.spaRouters = new spaRouters();
})()


案例如下:

1、創建靜態.html/.htm文件;

2、在html中創建文檔元素
<a href="#/login">測試1</a>,
<a href="#/register">測試2</a>
<a href="#/main">測試3</a>
“#”后代表的是相對應的內容;

3、分別創建3個
login.js
index.js
main.js腳本文件;
4、注冊路由 : 
spaRouters.map('/index',function(transition){
//異步加載js
spaRouters.asyncFun('index.js',transition)
//或者同步執行回調
//spaRouters.syncFun(function(transition){},transition)
})

5、login.js腳本代碼如下:
   SPA_RESOLVE_INIT = function(transition) {
  alert("請登錄");
}
5、index.js腳本代碼如下:
   SPA_RESOLVE_INIT = function(transition) {
  alert("測試1");
}

5、main.js腳本代碼如下:
   SPA_RESOLVE_INIT = function(transition) {
  alert("測試2");
}

6、初始化:spaRouters.init();


結束語:

   本文下筆之處還以為會發現一些好玩的東西,后來發現自己想多了。

  整理來整理去,最后就成了一個比較詳盡的文檔了。

  之后寫組件,我會借助些原生的已經內置好的方法來實現,可以省去不少功夫,會很有意思。

  日后的精彩演繹源自平時平淡的積累。

  對於大部分的人,對於本文這些是無感的,想不到如何在實際項目中應用,覺得很雞肋,實際上大有可為的,我已經想要躍躍欲試了,嘿嘿。

  如有疑問,請各位基佬們私聊或留言,我的大哥大25英寸的手機一直帶着身上,可隨時聯系我......




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM