爪哇学习笔记——从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路由

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方法看前端路由)