我通过以下方式解决了这个问题:;
-
每次创建历史状态时,我都会生成一个时间戳作为guid
-
当前时间戳存储在顶层模块的变量中
-
发生popstate时,将传入历史记录状态的guid与顶级模块guid进行比较
-
如果新的guid更大,我们将前进,如果它更少,我们将后退
-
当用户单击后退/前进按钮时,哈希确实会更改为输入URL。如果用户单击“取消”,它将运行历史记录。go(方向),其中方向为1或-1,具体取决于时间戳。这会将URL设置回它应该的状态,并且不会对历史堆栈做任何奇怪的事情。顶层历史变量有一个标志,表明我们正在伪造页面更改,因此不会执行popstate中的链接加载逻辑。
唯一的怪癖是,当发送和返回请求并创建历史对象时,如果用户确实单击“是”导航离开,则不会更新顶级模块的guid。如果您进行guid比较,则会始终认为您正在后退,因为您刚才添加的新事件将始终是最大的数字。如果您没有对历史URL发出新请求,这可能不是问题,但我们的框架会这样做,它不会像浏览器通常那样显示过时的数据。
这并不理想,因为您确实看到了URL的更改(没有内容更改),但到目前为止,它似乎工作得足够好。我发现的另一个解决方案是将自己站点的历史记录存储在本地/会话存储中,并比较URL,而不是使用guid时间戳来查找popstate方向。这在Safari的私有浏览模式下不起作用,因为两个存储层都被禁用,所以我选择了guid。