Open beita1991 opened 7 years ago
做微信企业应用开发时,业务代码用的是react,路由用的react-router。遇到一种场景,列表页面(A)、选中项详情(B)、编辑功能(C)、选人功能(D),正常效果是 A-->B-->C-->D,然而D操作完后会跳转到B页面。用户点击左上角的微信应用自带返回按钮,这个时候返回到的是D页面,但是这个不是我想要的效果,我希望的是返回到A页面。
从分析中可以看出应该与对应的 history Api 有关 ,查看相关 Api 与google了一番,发现了这遍blog 如何监听用户点击浏览器后退按钮。 代吗如下:
//监听hashchange事件 window.addEventListener('hashchange', function() { //为当前导航页附加一个tag this.history.replaceState('hasHash', '', ''); console.error('==============监听hashchange事件================') }, false); window.addEventListener('popstate', function(e) { if (e.state) { //侦测是用户触发的后退操作, dosomething //这里刷新当前url console.error('侦测是用户触发的后退操作',e.state) } }, false);
构建一个浏览历史存储对象,每次跳转将数据存储进去
historyObject: { urlList: [], // 浏览历史 currentIndex: -1, }
这样可以知道浏览器的前进后退,然后将 对应的url与 urlList 中数据作比较,设置对应的index。 回到问题中用户D跳转到B,已知URL只要匹配 urlList 中数据然后找到对应的index,然后执行 history.go 去跳转。考虑到用户刷新操作,所以将数据变更存储到 localStorage 中 之后的工作就维护好这个 historyObject 对象。 丰富后的代码如下:
function urlFilter(url) { let index = url.indexOf('_k='); if (index > 0) { url = url.substring(0, index - 1); } return url; } let HistoryManager = { /** * 记录 history 列表 * { * urlList:[], ['url_a','url_b'] * currentIndex: -1, * } */ historyObject: { urlList: [], currentIndex: -1, }, localStorageHistoryKey: 'HISTORY_MANAGER_LIST_KEY', // 初始化调用 initialize() { // 初始化的时候判断localStory中是否有相关数据,如果有将其取出 let historyObject = window.localStorage.getItem(this.localStorageHistoryKey); if (historyObject) { this.historyObject = JSON.parse(historyObject); } //监听hashchange事件 window.addEventListener('hashchange', ()=>this.hashchangeEvent(), false); window.addEventListener('popstate', (e)=>this.popstateEvent(e), false); }, hashchangeEvent(){ window.history.replaceState('hasHash', '', ''); }, popstateEvent(e){ if (e.state) { let url = urlFilter(window.location.href); let index = this.historyObject.urlList.findIndex((item, i) => item == url); this.setHistoryObject({ currentIndex: index, urlList: this.historyObject.urlList, }); } }, removeEventListenter(){ window.removeEventListener('hashchange',this.hashchangeEvent); window.removeEventListener('popstate',this.popstateEvent); }, getHistoryObject(){ return this.historyObject; }, setHistoryObject(historyObject){ this.historyObject = historyObject; if (window.localStorage.getItem(this.localStorageHistoryKey)) { window.localStorage.removeItem(this.localStorageHistoryKey); } window.localStorage.setItem(this.localStorageHistoryKey, JSON.stringify(this.historyObject)); window.beitaTestHistory = this.historyObject; }, compareUrl(newUrl, oldUrl){ if (newUrl && oldUrl) { return newUrl === oldUrl; } throw {errorMessage: "HistoryManager.compareUrl 方法传入参数有误"}; return false; }, /** * 跳转 --这里只是存储数据,跳转是在调用当前方法时候用的 react-router 封装history对象 的 push方法 */ navTo(url){ let {currentIndex, urlList}= this.historyObject; if (currentIndex > -1) { // 删除当前 currentIndex 后面的数据 再将 url添加进去 if (currentIndex != (urlList.length - 1)) urlList = urlList.splice(0,currentIndex+1); urlList.push(url); this.setHistoryObject({ currentIndex: currentIndex + 1, urlList: urlList, }) } else { throw {errorMessage: "未找到当前url"}; } }, popTo(url){ url = urlFilter(url); let index = this.historyObject.urlList.findIndex((item, i) => item == url); this.go(index-this.historyObject.currentIndex); }, /** * 替换 --这里只是存储数据,跳转是在调用当前方法时候用的 react-router 封装 history 对象 的 replace 方法 */ replaceTo(url){ url = urlFilter(url); let {currentIndex, urlList}= this.historyObject; urlList[currentIndex]= url; this.setHistoryObject({ currentIndex: currentIndex, urlList: urlList, }) }, getCurrentHistory(){ return this.historyObject.urlList[this.historyObject.currentIndex] || undefined; }, getCurrentHistoryIndex(){ return this.historyObject.currentIndex; }, back(){ this.go(-1); }, forward(){ this.go(1); }, go(n){ window.history.go(n); }, }; module.exports = HistoryManager;
能否详细的讲一下HistoryManager怎么用吗?或者有没有demo之类的?
@beita1991 赞👍
移动端H5单页面应用路由变化与默认返回按钮效果不搭配解决方案
功能与需求
做微信企业应用开发时,业务代码用的是react,路由用的react-router。遇到一种场景,列表页面(A)、选中项详情(B)、编辑功能(C)、选人功能(D),正常效果是 A-->B-->C-->D,然而D操作完后会跳转到B页面。用户点击左上角的微信应用自带返回按钮,这个时候返回到的是D页面,但是这个不是我想要的效果,我希望的是返回到A页面。
分析与提出问题
解决
从分析中可以看出应该与对应的 history Api 有关 ,查看相关 Api 与google了一番,发现了这遍blog 如何监听用户点击浏览器后退按钮。 代吗如下:
构建一个浏览历史存储对象,每次跳转将数据存储进去
这样可以知道浏览器的前进后退,然后将 对应的url与 urlList 中数据作比较,设置对应的index。 回到问题中用户D跳转到B,已知URL只要匹配 urlList 中数据然后找到对应的index,然后执行 history.go 去跳转。考虑到用户刷新操作,所以将数据变更存储到 localStorage 中 之后的工作就维护好这个 historyObject 对象。 丰富后的代码如下:
总结