问题背景

在单页应用中,翻页一般通过display:none将先前的面板(一般就是个div容器)隐藏,然后将本次需要展现的面板设置成display:block(当然,还可能加点css切换动画,不过不影响我们本次的讨论结果,故不予关注),一般情况下,这样的处理方式是没啥问题的,不过如果之前的面板本身有滚动条,那么跳转到新面板之后再返回到原先面板就会导致滚动条位置直接变成0,这主要是当元素的display为none时,元素不占据位置,等到display非none的时候才会被重新布局,渲染。

我们以jq.ui(一个用于构建jqMobi应用的用户界面库)为例说明下怎么解决单页应用中切换页面导致的滚动条位置信息丢失问题

思路

在老页面被display:none之前用一个堆栈存储下当前页面的滚动条位置,然后在用户点击浏览器返回按钮的时候取出栈顶记录的滚动条位置信息并调用window.scroll滚动到指定位置即可。

基于jq.ui的实例

1、在jq.ui源码中页面切换之前手动触发个事件(用于在自己的代码中捕捉此事件并记录老页面滚动条位置信息)

/*在老的panel被display:none之前触发beforeHideOldPanel事件,
*用于记录当前滚动条位置,以便于返回上一页时滚动到指定位置*/
jq(oldDiv).trigger('beforeHideOldPanel');

2、在页面上监听第一步中触发的beforeHideOldPanel事件和popstate(浏览器回退事件)以及loadpanel(加载面板事件),当beforeHideOldPanel事件被触发且当前不在回退时记录滚动条位置,当loadpanel事件被触发且当前正在回退时从堆栈中取出滚动条位置并调用window.scroll手动滚动到指定位置

// 由于jq.wow.js中通过display:none方式切换面板,导致老的panel滚动条信息丢失
// (display:none元素无高度),点击返回上一页时会自动定位到顶部
// 此处通过一个简单的堆栈记录老页面的滚动条信息,退回上一页时手动调用window.scroll滚动到指定位置
function resetScrollWhenPopstate() {//借助数组实现个简单的堆栈var scrollStack = {list: [],push: function (obj) {this.list.push(obj);},pop: function () {return this.list.pop();}};$('.panel').on('beforeHideOldPanel', function (e) {// 仅非回退时才记录滚动条位置if (!isPopStating) {scrollStack.push({oldPageId: e.currentTarget.id,oldScrollTop: document.documentElement.scrollTop || document.body.scrollTop});}}).on('loadpanel', function (e) {// 仅回退页时才恢复滚动条位置if (isPopStating) {var obj = scrollStack.pop();if (obj && obj.oldPageId == e.currentTarget.id) {window.scroll(0, obj.oldScrollTop);}}});// 标示是否正在回退var isPopStating = false;window.addEventListener('popstate', function () {isPopStating = true;setTimeout(function () {isPopStating = false;}, 200);});
}

总结

看似简单的堆栈其实还是有挺大用处的,算法和数据结构这东西看来还是需要学习学习(@ο@) 哇~

如何用堆栈来保存和恢复滚动条位置相关推荐

  1. 保存和恢复桌面上的图标位置

    保存和恢复桌面上的图标位置 - CodeProject 本文介绍如何在 Windows 桌面上保存和还原图标的位置. 下载源代码 - 181.9 KB 介绍 最近,我的公司为我的笔记本电脑提供了一个扩 ...

  2. QPainter 的状态保存与恢复

    实现这样的一个程序,把 QPainter 的坐标原点从左上角移动到 (100, 100),然后画出坐标轴,接下来顺时针旋转坐标轴 45 度,设置画笔,画刷,字体,画一个矩形和字符串,最后恢复 QPai ...

  3. C28x 中断上下文的保存和恢复

    C28x 上下文保存和恢复 介绍 本文介绍了 C28x CPU 的自动上下文保存/恢复.这也适用于带有 FPU 和 VCU 扩展的设备. 其他资源 上下文保存和恢复的详细内容在 <C28x TM ...

  4. Git常用操作(清除工作区未跟踪文件、保存和恢复进度、打标签)

    git clean 清除工作区未跟踪文件 git clean 命令去除冗余文件或者清理工作目录 git clean -f -d 移除工作目录中所有未追踪的文件以及空的子目录.(-f强制删除) git ...

  5. Tensorflow |(5)模型保存与恢复、自定义命令行参数

    Tensorflow |(1)初识Tensorflow Tensorflow |(2)张量的阶和数据类型及张量操作 Tensorflow |(3)变量的的创建.初始化.保存和加载 Tensorflow ...

  6. 简单完整地讲解tensorflow模型的保存和恢复

    http://blog.csdn.net/liangyihuai/article/details/78515913 在本教程主要讲到: 1. 什么是Tensorflow模型? 2. 如何保存Tenso ...

  7. 保存和恢复应用程序状态

    在实际应用中,常常需要应用程序能保存程序的状态以及用户的设置,如应用程序显示的大小.位置.背景颜色或用户设置参数等信息,以便下次运行程序时,能保持上次关闭的状态. Qt提供的QSettings类能很方 ...

  8. Tensorflow【实战Google深度学习框架】TensorFlow模型的保存与恢复加载

    我们使用TensorFlow进行模型的训练,训练好的模型需要保存,预测阶段我们需要将模型进行加载还原使用,这就涉及TensorFlow模型的保存与恢复加载. 总结一下Tensorflow常用的模型保存 ...

  9. Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复

    Android中的状态保存和恢复 Android中的状态保存和恢复, 包括Activity和Fragment以及其中View的状态处理. Activity的状态除了其中的View和Fragment的状 ...

最新文章

  1. qtp9.2测试java_QTP的使用举例说明
  2. 解决导航守卫router.beforeResolve使用不了this.$store
  3. 利用二叉树的思想来实现分配和释放内存方法
  4. java if and_关于java:if语句中可以有两个条件吗
  5. 关于Linux和Windows的换行符
  6. LInux线程——多线程与fork之间的问题
  7. python使用正则化预处理数据
  8. 如何用Sql更新默认值
  9. [转载] python价值算法_PangRank算法原理及其Python实现
  10. 谷歌浏览器安装插件的方法
  11. jtds 支持 mysql 吗?_jTDS驱动兼容性问题
  12. 设置Windows10系统下电脑屏幕自动关闭的时间(只关闭屏幕,电脑主机不关机)
  13. 联想服务器AR系列,联想正式发布AR一体机:晨星AR
  14. 吴恩达机器学习笔记——含一个隐藏层的神经网络
  15. HTTP 接口设计指北
  16. 为什么说DAO是未来的公司形式
  17. c语言 取余 % 和除法 / 的应用技巧 (在取位数方面的)
  18. 一个u盘大小的树莓派就能搭建一个服务器
  19. 将exe4j打包的java exe程序反编译过程
  20. CMake中find_package的学习

热门文章

  1. toString()方法使用
  2. java语言编程基础_java语言编程基础
  3. shell实战之tomcat看门狗
  4. ssh登陆报错“WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!”的解决方法
  5. 怎么样开会才有效果?
  6. linux 下访问mysql
  7. 谷歌移动应用强调设计元素:向极简风格转型
  8. ecshop分页类assign_pager分析和扩展
  9. tensorflow 启动Session(tf.Session(),tf.InteractivesSession(),tf.train.Supervisor().managed_session() )
  10. 如何使用War包部署Tomcat