手写简单路由Router hash和history两种实现
手写简单hash router
<a href="#">首页</a>
<a href="#/news">新闻页</a>
<div id="content"></div>
// 添加路由规则
Router.prototype.route = function(path, cb){
// 存储path对应的回调函数
this.routes[path] = cb || function(){};
}
// 路由刷新
Router.prototype.refresh = function(){
// 获取当前url的hash值
this.currentUrl = location.hash.slice(1) || '/'; // slice(1)从第二个开始截取到最后一位,第0个舍弃,舍弃了#
console.log(this, this.currentUrl);
// 执行当前路由回调函数
console.log(this.routes)
console.log(this.routes[this.currentUrl])
this.routes[this.currentUrl] && this.routes[this.currentUrl]();
}
// 窗口监视
Router.prototype.init = function(){
// 窗口监视hash变化事件,从而自动触发该路由规则
window.addEventListener('load', this.refresh.bind(this));
window.addEventListener('hashchange',this.refresh.bind(this));
}
function Router() {
// 路由目录
this.routes = {};
// 当前url地址
this.currentUrl = '';
this.init();
}
var router = new Router();
router.route('/', function () {
var div = document.querySelector('#content');
div.innerHTML = '<h2>这是首页</h2>';
})
router.route('/news', function () {
var div = document.querySelector('#content');
div.innerHTML = '<h2>这是新闻页</h2>';
})
history实现方式
本地跑不起来,需要在服务环境运行
<a href="/home">home</a>
<a href="/about">about</a>
<div id="container"></div>
let aEl = document.getElementsByTagName('a');
let container = document.getElementById('container');
// 使用history模式就要进制a标签跳转,用a标签点击事件进行路由跳转
[].slice.call(aEl).forEach(item => {
item.addEventListener('click', function (e) {
// 禁止a标签跳转
e.preventDefault();
let href = e.target.getAttribute('href');
// 在浏览器中添加一条历史记录,并且将当前路径地址保存到state中
history.pushState({ pathname: href }, null, href);
// 然后根据href进行一些视图渲染,比如/home显示什么、/about显示什么
container.innerHTML = `<h2>${href.slice(1)}组件</h2>`;
}, false);
})
// 监听popstate事件,一般浏览器前进后退时触发
window.addEventListener('popstate', function (e) {
// 浏览器前进后退时根据e.state中的信息进行视图渲染
container.innerHTML = `<h2>${e.state.pathname.slice(1)}组件</h2>`;
}, false);