1.基于hash路由模式
原理:hash路由模式,形如http://xxx.com/index#xx,#后面的xx就是hash值,一旦改变#的hahs值,不会发送请求,但会触发hashchange事件,因此可以通过监听hashchange事件来实现路由。
简单的demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hash路由demo</title>
</head>
<body>
<ul>
<li><a href="#/">this is index</a></li>
<li><a href="#/product">this is product</a></li>
<li><a href="#/server">this server</a></li>
</ul>
</body>
</html>
class HashRouter {
constructor() {
// 存储hash与callback键值对
this.routes = {};
// 保存当前的hash
this.currentHash = '';
// 绑定事件
const hashChangeUrl = this.hashChangeUrl.bind(this);
// 页面加载事件
window.addEventListener('load', hashChangeUrl, false);
// 监听hashchange事件
window.addEventListener('hashchange', hashChangeUrl, false);
}
// path路径和callback函数对应起来,并且使用 上面的this.routes存储起来
route(path, callback) {
this.routes[path] = callback || function() {};
}
hashChangeUrl() {
/*
获取当前的hash值
location.hash 获取的值为:"#/a, 因此 location.hash.slice(1) = '/a' 这样的
*/
this.currentHash = location.hash.slice(1) || '/';
// 执行当前hash对应的callback函数
this.routes[this.currentHash]();
}
}
// 初始化
const Router = new HashRouter();
const body = document.querySelector('body');
const changeColor = function(color) {
body.style.backgroundColor = color;
};
// 注册函数
Router.route('/', () => {
changeColor('red');
});
Router.route('/server', () => {
changeColor('green');
});
Router.route('/product', () => {
changeColor('#CDDC39');
});
2.基于history路由模式
这种模式核心是借助history的pushState实现,window.pushState(state,data,path);pushState改变url但是不刷新,pushState会向history添加一个浏览记录,类似的函数有replaceState(state,data,path),该函数会替换history顶部的浏览记录。
需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法)
<body>
<ul>
<li>
<a href="/"> this is index</a>
</li>
<li>
<a href="/a"> this is a</a>
</li>
<li>
<a href="/b">this is b</a>
</li>
</ul>
</body>
在这里插入代码片class HistoryRoutes {
constructor() {
// 保存对应键和函数
this.routes = {};
// 监听popstate事件
window.addEventListener('popstate', (e) => {
const path = this.getState();
this.routes[path] && this.routes[path]();
});
}
// 获取路由路径
getState() {
const path = window.location.pathname;
return path ? path : '/';
}
route(path, callback) {
this.routes[path] = callback || function() {};
}
init(path) {
history.replaceState(null, null, path);
this.routes[path] && this.routes[path]();
}
go(path) {
history.pushState(null, null, path);
this.routes[path] && this.routes[path]();
}
}
window.Router = new HistoryRoutes();
console.log(location.pathname);
Router.init(location.pathname);
const body = document.querySelector('body');
const changeColor = function(color) {
body.style.backgroundColor = color;
};
// 注册函数
Router.route('/', () => {
changeColor('red');
});
Router.route('/product', () => {
changeColor('green');
});
Router.route('/server', () => {
changeColor('#CDDC39');
});
const ul = document.querySelector('ul');
ul.addEventListener('click', e => {
console.log(e.target);
if (e.target.tagName === 'A') {
e.preventDefault();
Router.go(e.target.getAttribute('href'));
}
});