爪哇学习笔记——从pushState方法看前端路由

History路由 在H5之前,浏览器的history对象只支持页面之间的跳转、前进和后退功能

history.length history.go(integer) history.back(integer) history.forward(integer)

在H5中新增了以下API:
history.pushState() history.replaceState() history.state

pushState和replaceState方法
调用pushState方法会向历史记录中添加一条新的记录,在改变页面URL的同时不会触发页面重新加载新,这个特性非常适用于前端路由。replaceState方法类似,只不过是替换记录,而不是新增。
popstate事件
每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。但是调用history.pushState()和history.replaceState()方法不会触发该事件。
创建路由类
class HistoryRouter{ constructor() { this.routes = {}; document.addEventListener('popstate', e => { const path = e.state && e.state.path; this.routes[path] && this.routes[path](); }) }initPath(path) { window.history.replaceState({path}, null, path); this.routes[path] && this.routes[path](); }route(path, callback) { this.routes[path] = callback || function() {}; }go(path) { history.pushState({path}, null, path); this.routes[path] && this.routes[path](); } }window.Router = new HistoryRouter();

注册路由
function changeBgColor(color){ content.style.background = color; }Router.route(location.pathname, () => { changeBgColor('yellow'); }); Router.route('/red', () => { changeBgColor('red'); }); Router.route('/green', () => { changeBgColor('green'); }); Router.route('/blue', () => { changeBgColor('blue'); }); const content = document.querySelector('body'); Router.init(location.pathname);

监听路由变化
在hash路由中,我们通过hashchange事件来监听路由变化,且hash变化不会触发页面加载。但是history路由就不太一样:
  • 点击标签跳转时,不只是hash改变,所以我们需要拦截它的默认行为,防止页面重新加载
  • 点击浏览器前进后退按钮时,会触发popstate事件,我们需要监听该事件来跳转路由(见HistoryRouter类构造函数中的监听)
    // a标签处理 const ul = document.querySelector('ul'); ul.addEventListener('click', e => { if(e.target.tagName === 'A'){ e.preventDefault(); Router.go(e.target.getAttribute('href')); } })

Hash路由 hash路由通过监听hashchange事件来感知路由变化,其他逻辑与history基本相似,这里不再详细介绍
class Routers{ constructor(){ // 保存路由信息 this.routes = {}; this.currentUrl = ''; window.addEventListener('load', this.refresh, false); window.addEventListener('hashchange', this.refresh, false); }// 用于注册路由的函数 route = (path, callback) => { this.routes[path] = callback || function(){}; }// 监听事件的回调,负责当页面hash改变时执行对应hash值的回调函数 refresh = () => { this.currentUrl = location.hash.slice(1) || '/'; this.routes[this.currentUrl](); } }window.Router = new Routers();

【爪哇学习笔记——从pushState方法看前端路由】参考文档:
前端路由的实现原理

    推荐阅读