学习第三方库-history

1,726 阅读2分钟

首先history是干嘛的:

history允许您轻松地管理JavaScript运行的任何地方的会话历史。history对象抽象出各种环境中的差异,并提供一个最小的API,允许您管理history堆栈、导航和持久化会话之间的状态。

接下来我们来看看history有哪些api可以使用

import {
createBrowserHistory
createHashHistory
createMemoryHistory
createPath
parsePath } from 'history'

首先我们需要先来了解一下前端路由监听的几种方式

  • hash:主要是基于锚点的原理实现。
  • browser:即使用html5标准中的history api通过监听popstate事件来对dom进行操作。每次路由变化都会引起重定向
  • memory:这种实现是在内存中维护一个堆栈用于管理访问历史的方式,比较复杂。在早起移动端使用比较多。实现麻烦,问题也较多。现在很少有使用。RN在使用这种路由模式
  • static:主要用于ssr。需要后端去管理路由

    通过hash改变,利用window.onhashchange 监听。

    调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法),此外,a 标签的锚点也会触发该事件.

    当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会.

    history.pushState(state, title, url)
    意思就是把一个history记录插入到历史记录中

    history.replaceState(state, title, url)
    用新的state和URL替换当前。不会造成页面刷新。


createBrowserHistory

浏览器历史记录将位置存储在常规url中。这是的标准 *大多数web应用程序,但它需要在服务器上进行一些配置,以确保您 *在多个url上提供相同的应用程序

  • 初始化工作

首先新创建的历史对象的默认动作为POP

然后它会创建2个事件队列listenersblockers

function createEvents() {
    var handlers = [];
    return {
        get() { return handlers.length },
        push(fn) {  
            handlers.push(fn)
        },
        call(arg) { 
            handlers.forEach((h) => h && h(arg))
        }
    }
}

通过window.historywindow.location获取浏览器当前会话的信息,如果此时的序列号(index)为0,说明浏览器重新渲染了当前页面,通过window.history.replaceState给当前的history添加状态信息idx(初始化值为0);

最后注册一个监听事件,window.addEventListener('popstate', handlePop);

  • 开始监听操作

如果这个时候blockers事件队列(handlers)为空的时候,否则调用listeners事件队列, 它的核心是applyTx方法

function applyTx(nextAction: Action) {    
    action = nextAction;    
    [index, location] = getIndexAndLocation();    
    listeners.call({ action, location });  
}

createHashHistory

同时监听window.addEventListener('popstate', handlePop)window.addEventListener('hashchange', handlePop)

createMemoryHistory

内存历史记录在内存中存储当前位置。它是为使用而设计的 *在有状态的非浏览器环境,如testsReact Native



参考地址

history库的地址 [github.com/ReactTraini…]

History的MDN[developer.mozilla.org/zh-CN/docs/…]