Hash

利用 hash 来实现,主要原理通过监听 # 后的 URL 路径标识符的更改而触发的浏览器 hashchange 事件,然后通过获取 location.hash 得到当前的路径标识符,再进行一些路由跳转的操作。

用到的 API

location.href:返回完整的 URL。
location.hash:返回 URL 的锚点部分。
location.pathname: 返回 URL 的路径名。
hashchange:当 hash 改变时,触发该事件。

  1. class RouterPolyfill {
  2. constructor() {
  3. this.routes = {}
  4. this.currentUrl = ''
  5. window.addEventListener('load', () => this.render())
  6. window.addEventListener('hashchange', () => this.render())
  7. }
  8. // 初始化
  9. static init() {
  10. window.Router = new RouterPolyfill()
  11. }
  12. // 路由注册
  13. registerRoute(path, cb) {
  14. this.routes[path] = cb || function () { }
  15. }
  16. // 执行回调函数
  17. render() {
  18. this.currentUrl = location.hash.slice(1) || '/'
  19. this.routes[this.currentUrl]()
  20. }
  21. }

hash.gif

完整版例子

HTML5 History Api

HTML 5 提供了一些常用的操作路由的 api,而这些 api 本身具有记录功能。

相关 api

在历史中移动

History.back():移到上一个网站。
History.forward:移到下一个网站。
History.go():接受一个整数作为参数,以当前网站为基准,移动到指定的网站。

修改历史

History.pushState():添加一条历史。
History.replaceState:修改当前历史。

事件

popstate :每当同一个文档的浏览历史(即 history 对象)出现变化时,就会触发 popstate 事件。

  1. class RouterPolyfill {
  2. constructor(path) {
  3. this.routes = {}
  4. history.replaceState({ path }, null, path)
  5. this.routes[path] && this.routes[path]()
  6. // 用于点击浏览器前进回退按钮时触发
  7. window.addEventListener('popstate', e => {
  8. const path = e.state && e.state.path
  9. this.routes[path] && this.routes[path]()
  10. })
  11. }
  12. // 初始化
  13. static init() {
  14. window.Router = new RouterPolyfill(location.pathname)
  15. }
  16. // 记录路由和回调函数
  17. registerRoute(path, cb) {
  18. this.routes[path] = cb || function () { }
  19. }
  20. // 路由跳转
  21. go(path) {
  22. history.pushState({ path }, null, path)
  23. this.routes[path] && this.routes[path]()
  24. }
  25. }

history.gif

完整版例子

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