模拟实现
2024年03月06日
一、Hash 模式
- HTML
- JavaScript
<div id="app">
<ul>
<li><a href="#/">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/detail">Detail</a></li>
</ul>
<div id="content"></div>
</div>
<script src="./hash.js"></script>
class Router {
constructor() {
this.routes = {};
this.currentUrl = '';
this.container = document.getElementById('content');
this.init();
}
init() {
window.addEventListener('load', this.updateView.bind(this), false);
window.addEventListener('hashchange', this.updateView.bind(this), false);
}
updateView() {
this.currentUrl = location.hash.slice(1) || '/';
this.routes[this.currentUrl] && this.routes[this.currentUrl]();
}
route(path, callback) {
this.routes[path] = callback || function () {};
}
push(path) {
window.location.hash = path;
}
updateInnerHTML(content) {
this.container.innerHTML = content;
}
}
const router = new Router();
router.route('/', () => {
router.updateInnerHTML('Home');
});
router.route('/about', () => {
router.updateInnerHTML('About');
});
router.route('/detail', () => {
router.updateInnerHTML('Detail');
});
setTimeout(() => {
router.push('/about');
}, 3000);
二、History 模式
- HTML
- JavaScript
<div id="app">
<div id="content"></div>
</div>
<script src="./history.js"></script>
class Router {
constructor() {
this.routers = {};
this.currentUrl = '';
this.container = document.getElementById('content');
}
route(path, callback) {
this.routers[path] = callback || function () {};
}
updateView(url) {
this.currentUrl = url;
this.routers[this.currentUrl] && this.routers[this.currentUrl]();
}
init(path) {
history.replaceState({ path: path }, null, path);
this.updateView(path);
}
push(path) {
history.pushState({ path: path }, null, path);
this.updateView(path);
}
listerPopState() {
window.addEventListener('popstate', e => {
const path = e.state && e.state.path;
this.updateView(path);
});
}
updateInnerHTML(content) {
this.container.innerHTML = content;
}
}
const router = new Router();
router.route('/', () => {
router.updateInnerHTML('Home');
});
router.route('/about', () => {
router.updateInnerHTML('About');
});
router.route('/detail', () => {
router.updateInnerHTML('Detail');
});
router.init('/');
setTimeout(() => {
router.push('/about');
}, 4000);