浏览器的记录栈和history API的应用

回顾

上篇博客,我使用hashchange函数来监听每次hash改变的时候,记录当前的scrollTop值到sessionStorage中,然后再进入该页面时就看sessionStorage中是否有记录值,如果有就在页面html内容全部加载完成后取出记录值使页面加载到同样的位置,如果没有记录就记录当前的位置。一波简单的操作之后,页面在hash变化的时候,确实能按照我们预期的那样进行着,非第一次进入一个页面,会保存上次浏览该页面的位置继续浏览,但是!当我在切换多个hash后,按物理键返回或点击页面的返回键的时候,页面并没有按照我当前记录的那样保存位置,而是发生了错乱。

问题调研

在一系列的断点调试的时候,终于找到了问题所在。假如有两个页面a(#a) 和b(#b),先从a页面跳到b页面,然后在b页面返回到a页面的时候,注意了!浏览器的行为这时候有点诡异,返回的时候,首先a的scrollTop值赋给当前页面!首先a的scrollTop值赋给当前页面!首先a的scrollTop值赋给当前页面!然后再改变hash,然后再渲染dom加载内容,那么一切都变得合理了
由于首先会把a的滚轮值给b页面,那其实这时候b的scrollTop值其实已经是a的了,然后再hash改变的时候,执行我们的hash监听函数,把b的scrollTop值(其实是a的位置记录)错误的更新了,当我们一直点返回,就会一直记录错的位置,只要返回到已经错误记录过的那个页面时,就会出现我们前面说的那种错误现象了。
那么找到问题所在了,原来这是单页面的特性使然,并不是代码问题,那解决也就变的简单了,只要让页面返回或者前进的时候,不执行我们定义的hashchange函数,也就是只要是页面返回或者前进的时候,就不记录当前的scrollTop值,让他只执行他的页面变化,,就OK了。
避免再次踩坑,我还是不急着解决该问题,而是决定彻底把浏览器的记录行为弄清楚先!!!

理解浏览器的历史记录

1.浏览器有一个类似栈的网页记录的数据结构,我把他叫做记录栈,在同一个窗口下,改变网页的时候,会把当前的网页记录推到记录栈中,刷新页面不会增加记录栈。浏览器有一个history对象,可以记录这种行为,但是只能通过length属性查看当前窗口消息历史记录的总数,不能查看当前栈里的情况,对于开发者来说,操作记录栈相当于操作一个黑箱子,所以

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用HTML5的History API来实现浏览器前进和后退按钮的例子: HTML代码: ``` <!DOCTYPE html> <html> <head> <title>History API Example</title> </head> <body> <h1>History API Example</h1> <button id="backBtn">Back</button> <button id="forwardBtn">Forward</button> <script src="script.js"></script> </body> </html> ``` JavaScript代码: ``` // 获取back和forward按钮 var backBtn = document.getElementById('backBtn'); var forwardBtn = document.getElementById('forwardBtn'); // 监听back和forward按钮的点击事件 backBtn.addEventListener('click', function() { window.history.back(); }); forwardBtn.addEventListener('click', function() { window.history.forward(); }); // 获取当前的历史状态 var currentState = history.state; // 创建一个新的历史状态 var newState = { page: 'example.html' }; // 使用pushState方法将新的历史状态添加到历史记录history.pushState(newState, 'Example Page', 'example.html'); // 监听popstate事件,当用户点击浏览器的前进或后退按钮时触发 window.addEventListener('popstate', function(event) { // 获取新的历史状态 var newState = event.state; // 更新页面内容 document.title = newState.page; }); ``` 在这个例子中,我们首先获取back和forward按钮并添加点击事件监听器,当用户点击这些按钮时,我们使用History API的back()和forward()方法来模拟浏览器的前进和后退按钮。 接下来,我们获取当前的历史状态,并使用pushState()方法将一个新的历史状态添加到历史记录中。在这个例子中,我们创建了一个包含页面名称的简单对象,并将其添加到历史记录中。 最后,我们监听popstate事件,当用户点击浏览器的前进或后退按钮时触发。在这个事件处理程序中,我们获取新的历史状态并更新页面的标题。在实际应用中,您可以使用这个事件处理程序来更新页面内容,以便与用户选择的历史状态相匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值