hash路由实现
众所周知,当我们的浏览器地址栏改变时会刷新页面.
然而hash却不会
hash即地址后的”#/123”类似的字符串
所以利用它我们可以做前端路由
实现的几个关键点(注意this是全局作用域中(非严格模式)):
如何获取当前hash
location.hash //"#/123"
监听hash改变事件
this.addEventListener('hashchange',function(){},false);
监听load(页面/加载)事件
监听的目的是为了用户在得到这段地址时,如果想在新的标签栏直接打开,此时并不会触发hash改变事件,所以我们要补充一个load事件
this.addEventListener('load',function(){},false);
何时注册“/”路由?
个人建议在this.onload时
写这个点的原因是我在一开始写的时候,是这么写”/“路由的回调函数的location.href = 'http://localhost:8080';
意思是重新加载主页
如果不在onload时候注册,就会因为监听了load事件造成页面无限循环加载
ps:不过后来不这么写了,2333地址栏的编码问题
地址栏获取到的字符编码和你js注册时候的字符编码是不一样的,因此比较时会不相等,造成不存在此路由
需要unescape([String])
下面实践:
let router=(function(){
return {
routes: {},
//模糊路由,即你无法在本地捕捉到准确数据
vagueRoutes: [],
vagueRoutesFun: [],
//当前路由
nowUrl: '',
route: function (url, callback) {
//路由注册,传入字符串
this.routes[url]=callback||function () {};
},
vagueRoute: function (reg, callback) {
//模糊路由注册,传入正则表达式
this.vagueRoutes.push(reg);
this.vagueRoutesFun.push(callback);
},
refresh: function () {
//路由执行
this.nowUrl=window.location.hash.slice(1)||'/';
try{
this.routes[this.nowUrl]();
}catch(err){
//计数器
let num=0;
this.vagueRoutes.forEach(function (item,index) {
if(item.test(this.nowUrl)){
this.vagueRoutesFun[index]();
num--;
}
num++;
},this);
if(num===this.vagueRoutes.length&&this.nowUrl!='/'){
//不存在的页面处理方式
}
}
},
init: function () {
//初始化
window.addEventListener('load', router.refresh.bind(router));
window.addEventListener('hashchange', router.refresh.bind(router));
window.onload = function () {
router.route('/', function () {
location.href = 'http://localhost:8080/';
})
}
}
}
})();