// 前端很多MVC都有路由模块,但兼容多浏览器的代码比较多。
// 这里根据H5新api popstate,监听路由变化,注册一到多个处理函数,没有兼容旧版浏览器的部分,代码量更少更简单,可独立使用。
// 处理函数接收hash部分,可参考backbone自行解析
// 已在线上运行
var Router = (function () {
var win = window;
/*
* 设置路由
*/
var getHash = function (url) {
url = url || win.location.href;
var match = url.match(/#(.*)$/);
return match ? match[1] : '';
};
var routeHandleCache = [];
function iterateRegistry(handles) {
var hash = getHash();
for (var i = 0, len = handles.length; i < len; i++) {
var handleFunc = handles[i];
if (!handleFunc) {
continue
} else {
var result = handleFunc(hash);
if (result === true) {
return
} else {
continue
}
}
}
}
return {
getHash: getHash,
//这里的注册将处理函数push进数组,hash发生改变是依次调用数组里的每个处理函数,处理函数自己决定如何处理,感觉这是最通用的
registry: function (handles) {
if ((typeof handles) == 'function') {
handles = [handles]
}
routeHandleCache = routeHandleCache.concat(handles);
if (this.started) {
iterateRegistry(handles);
}
//console.log('注册处理函数', routeHandleCache)
},
navigate: function (hash) {
hash = hash || '';
var url = hash.indexOf('#') == 1 ? hash : '#' + hash;
location.href = url;
},
toView: function (path) {
Router.navigate(path)
},
/**
* 页面一开始没有hash,这个时候page或许也都没注册,所以需要一个启动函数,在page注册后处理hash为''的情况
*/
start: function () {
var __initRegistry = false;
win.addEventListener('popstate', function () {
this.started = true;
iterateRegistry(routeHandleCache);
__initRegistry = true;
}.bind(this));
//修复部分浏览器默认 首次进入页面会执行次popstate,某些不会的差异情况修复
setTimeout(()=> {
if (!__initRegistry) {
iterateRegistry(routeHandleCache);
}
}, 200);
this.navigate(getHash())
}
};
})();
module.exports = Router;
网友评论