Hash
利用 hash 来实现,主要原理通过监听 # 后的 URL 路径标识符的更改而触发的浏览器 hashchange 事件,然后通过获取 location.hash 得到当前的路径标识符,再进行一些路由跳转的操作。
用到的 API
location.href:返回完整的 URL。location.hash:返回 URL 的锚点部分。location.pathname: 返回 URL 的路径名。hashchange:当 hash 改变时,触发该事件。
class RouterPolyfill {constructor() {this.routes = {}this.currentUrl = ''window.addEventListener('load', () => this.render())window.addEventListener('hashchange', () => this.render())}// 初始化static init() {window.Router = new RouterPolyfill()}// 路由注册registerRoute(path, cb) {this.routes[path] = cb || function () { }}// 执行回调函数render() {this.currentUrl = location.hash.slice(1) || '/'this.routes[this.currentUrl]()}}

HTML5 History Api
HTML 5 提供了一些常用的操作路由的 api,而这些 api 本身具有记录功能。
相关 api
在历史中移动
History.back():移到上一个网站。History.forward:移到下一个网站。History.go():接受一个整数作为参数,以当前网站为基准,移动到指定的网站。
修改历史
History.pushState():添加一条历史。History.replaceState:修改当前历史。
事件
popstate :每当同一个文档的浏览历史(即 history 对象)出现变化时,就会触发 popstate 事件。
class RouterPolyfill {constructor(path) {this.routes = {}history.replaceState({ path }, null, path)this.routes[path] && this.routes[path]()// 用于点击浏览器前进回退按钮时触发window.addEventListener('popstate', e => {const path = e.state && e.state.paththis.routes[path] && this.routes[path]()})}// 初始化static init() {window.Router = new RouterPolyfill(location.pathname)}// 记录路由和回调函数registerRoute(path, cb) {this.routes[path] = cb || function () { }}// 路由跳转go(path) {history.pushState({ path }, null, path)this.routes[path] && this.routes[path]()}}

参考:
[1] 前端路由跳转原理
[2] History 对象 — Javascript 标准入门教程
