单页网站浏览器后退按钮仅生效一次的问题求助
问题分析与解决方案
核心问题出在回退操作时重复添加历史记录:当你点击后退触发onpopstate后,dispPage会调用displayPage,而原代码里的displayPage无条件执行history.pushState——这相当于在回退完成后,又往浏览器历史栈里新增了一条和当前状态完全一致的记录。再次点击后退时,浏览器实际是在这条重复记录和前一条之间切换,导致onpopstate无法触发预期的页面回退行为。
修复方案
给displayPage新增一个参数,区分「主动跳转」和「回退触发」两种场景,仅在主动跳转时添加历史记录:
- 修改
displayPage函数:
displayPage = function (page, json, isPopState) { // 仅非回退触发的场景,才新增历史记录 if (!isPopState) { var stateObj = { "page": page, 'json': json }; history.pushState(stateObj, "", page); } // 原有的页面渲染逻辑 // some code here }
- 修改
dispPage的调用逻辑,传入回退标记:
this.dispPage = function(blob){ // 标记为回退触发,跳过pushState displayPage(blob.page, blob.json, true); }
额外优化(可选)
部分浏览器(如Chrome)会在页面初始加载时触发一次无意义的onpopstate,可以添加标记忽略这次触发:
$(function() { Skeleton._construct(); var isFirstLoad = true; window.onpopstate = function(event) { if (isFirstLoad) { isFirstLoad = false; return; } // 确保state存在,避免空值报错 if (event.state) { Skeleton.dispPage(event.state); } } });
调整后,浏览器历史栈会保持正常的顺序,多次点击后退按钮时onpopstate事件就能正常触发了。
内容的提问来源于stack exchange,提问作者Fangster
相关产品推荐
相关产品推荐

