
2.5.4 hashHistory事件处理
hashHistory监听了浏览器的hashchange事件,用以获知浏览器地址的变化。对于hashHistory,除了单击浏览器的“前进”和“后退”按钮时会触发hashchange事件,hashHistory的push或replace方法由于改变了hash,同样会触发hashchange事件,这与browserHistory在内部处理上会有一些不同。
由于hashHistory的push或replace方法改变了hash会触发hashchange事件,因此hashchange事件的事件响应函数需要判断事件的触发来源,是来源于栈指针移动,如go(1)、go(-1),还是使用push、replace方法改变hash产生的hashchange事件。若不进行判断,则所有的导航都将在hashchange的事件响应函数中更新导航状态的action为“POP”。在源码实现上,在push或replace方法中会触发一次导航状态为“PUSH”或“REPLACE”的导航行为,且会对push或replace方法的导航路径做一次存储标记。如果在hashchange事件中获得的路径与使用push或replace方法设置的路径一致,则表明已经通过使用push或replace方法产生了导航行为,那么在hashchange事件中将不对此次事件响应做任何处理:

在browserHistory中,browserHistory的popstate监听函数不会特意对两次相同导航做出处理,这意味着同样的路径变化都会触发history.listen监听的回调函数。如前后两次路径相同的回退操作:

而如果hashHistory在某些情况下进行两次路径相同的回退操作,则回调函数不会触发两次:

这也是模拟了原生hashchange事件的行为:

但与原生行为不同的是,进行2次路径相同的push操作或replace操作都会触发history.listen监听的回调函数。但是,相同路径push函数调用会得到对应的警告,为了与原生行为保持一致,其不会使历史栈增加:


而replace函数调用不会得到警告,因为其不会影响历史栈的记录数量。