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.path
this.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 标准入门教程