实现H5路由和Hash路由
H5路由的实现:
主要是监听当点击前进后退键触发的popstate事件以及当发生路由跳转时触发的pushstate事件,这里没有用到replacestate事件
<div id="container">
<a href="./">首页</a>
<a href="./about">关于我们</a>
<a href="./user">用户列表</a>
</div>
<div id="context"></div>
<script>
class BaseRouter {
constructor() {
this.routes = {};
this._bindPopstate(); // _bindPopstate方法监听浏览器go()和back()触发的popState事件
}
route(path, callback) {
this.routes[path] = callback || function () {
}
}
go(path) {
window.history.pushState({path}, null, path);
const cb = this.routes[path];
if (cb) {
cb();
}
}
_bindPopstate() {
window.addEventListener('popstate', e => {
const path = e.state && e.state.path;
this.routes[path] && this.routes[path]();
})
}
}
const Route = new BaseRouter();
Route.route('./about', () => changeText("关于我们页面"));
Route.route('./user', () => changeText("用户列表页"));
Route.route('./', () => changeText("首页"));
function changeText(arg) {
document.getElementById('context').innerHTML = arg;
}
document.getElementById('container').addEventListener('click', e => {
if (e.target.tagName === 'A') {
e.preventDefault();
Route.go(e.target.getAttribute('href'))
}
})
</script>
Hash路由:
相对简单,主要监听hashchange这一个事件,当页面加载时需要监听load事件防止白屏
<div id="container">
<button onclick="window.location.hash = '#'">首页</button>
<button onclick="window.location.hash = '#about'">关于我们</button>
<button onclick="window.location.hash = '#user'">用户列表</button>
</div>
<div id="context"></div>
<script>
class BaseRouter {
constructor() {
this.routes = {};
this.refresh = this.refresh.bind(this);
window.addEventListener('load', this.refresh);
window.addEventListener('hashchange', this.refresh);
}
route(path, callback) {
this.routes[path] = callback || function () {
}
}
refresh() {
const path = `/${window.location.hash.slice(1) || ''}`;
this.routes[path]();
}
}
const Route = new BaseRouter();
Route.route('/about', () => changeText("关于我们页面"));
Route.route('/user', () => changeText("用户列表页"));
Route.route('/', () => changeText("首页"));
function changeText(arg) {
document.getElementById('context').innerHTML = arg;
}
</script>