JavaScript实现监听路由变化

692 阅读2分钟

下午摸鱼摸久了,突然想到前端应该怎么监听路由变化,搜了一下发现这个JavaScript如何实现history路由变化监听 - 掘金 (juejin.cn),感觉两个类套来套去有点混了,仿照这个自己实现一个简易版,正好理解一下发布订阅模式

// 定义类
class HistoryListener {  
  public listeners: object;  
  constructor() {  
    this.listeners = {};  
  }  
  addListener(name, fn) {  
    const clearId = Date.now();  
        this.listeners[name] = this.listeners[name] ? this.listeners[name].concat[{ fn, clearId }] : [{ fn, clearId }];  
    return clearId;  
  }  
  notifyListener(name) {  
    this.listeners[name].forEach((item) => item.fn());  
  }  
  removeListener(name: string, id: number) {  
    const index = this.listeners[name].findIndex(item => item.clearid === id);
    this.listeners[name].splice(index, 1);
  }  
}  
    

const instance = new HistoryListener();  

// 定义覆写history方法,在hisroty方法中插入逻辑,通知实例
const coverHistory = (name, instance) => {  
  const method = history[name];  
  return function () {  
    method.apply(history, arguments);  
    instance.notify(name);  
  };  
}  
// 覆写history方法
// 先保存一份原始方法
const ORIGIN_PUSHSTATE = history.pushState;
cosnt ORIGIN_REPLACESTATE = history.replaceState; 
history.pushState = coverHistory('pushState', instance);
history.replaceState = coverHistory('replaceState', instance);  

// 测试代码
const clearId1 = instance.addListener('pushState'() => {  
  console.log('窗口的history改变了');  
});  
const clearId2 = instance.addListener('pushState'() => {  
  console.log('窗口的history改变了-我也听到了');  
});  
 
// 移除监听
instance.removeListener('pushState', clearId1);  
instance.removeListener('pushState', clearId2);

第一次发文章,怎么还没到400字,开始水了!!!

前端实现路由变化主要有两种方式,分别是通过onHashChange, 和HTML5新加的historyAPI实现URL切换无刷新功能,也是目前单页面应用实现的大部分方式

通过hash改变,利用window.onhashchange 监听。 通过history的改变,进行js操作加载页面,然而history并不像hash那样简单,因为history的改变,除了浏览器的几个前进后退(使用 history.back(), history.forward()和 history.go() 方法来完成在用户历史记录中向后和向前的跳转。)等操作会主动触发popstate 事件,pushState,replaceState 并不会触发popstate事件。

上文中实现了监听history,pushState、replaceState方法, 最后我们只需要再监听window的popstate

window.onpopstate = functino (){
    console.log('popstate事件触发')
}

参考链接在这里JavaScript如何实现history路由变化监听 - 掘金 (juejin.cn),有兴趣可以对比下,希望能收到各位前辈、同仁建议,嘻嘻