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

问题背景

在单页应用中,翻页一般通过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);});
}

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Hibernate中维护表的历史记录

为了维护数据库的历史记录或跟踪数据库表行的修改,我们创建了一个版本表,其中包含与原始表相同的字段。每当原始表被更改时,我们都会在版本表中创建另一个条目。 因此,对于每个更新查询,我们都必须在版本表中编写一个插…

java批量提取文件夹名称_bat 批量提取指定目录下的文件名

bat 批量提取指定目录下的文件名下面是批量获取指定目录下的文件名的核心代码echo offecho text inputset inputset /p input:echo %input% is inputcd %input%rem echo onfor %%a in (*) do (echo %%a is input)cd ..如下是sql server执行对应脚本文件sqlcmd -Spcserver -dmas…

埃及分数The Rotation Game骑士精神——IDA*

IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题。 估价函数设计思路:观察一步最多能向答案靠近多少。 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一…

[UE4]创建Shooter基类,2种方法

一、可以通过直接修改"BP_FPPCharacter"的名字为“BP_Shooter”作为基类,然后新建一个"BP_FPPCharacter"继承自“BP_Shooter”。 这种方法适用于各个类对"BP_FPPCharacter"依赖不多的情况。 二、创建一个“BP_Shooter”继承于“Chara…

美团扫码付的前端可用性保障实践

开篇 2017年,美团金融前端遇到了很多通用性问题,特别是在保障前端可用性的过程中,我们团队也踩了不少“坑”,在梳理完这些问题以后,我们还专门做了第31期线下沙龙给大家进行了分享。不管是在面试过程中与候选人讨论&a…

Servlet上传文件和下载文件示例

Java Web应用程序中的文件上载和下载以及常见任务。 由于最近我写了很多有关Java servlet的文章 ,因此我想提供一个使用servlet上传和下载文件的示例示例。 用例 我们的用例是提供一个简单HTML页面,客户端可以在其中选择要上传到服务器的本地文件。 在提…

用java单源最短路径问题_单源最短路径-贪心算法

单源最短路径,关于这个问题的贪心算有点不好理解,分析后续补充,代码也需要后续优化,便于理解package test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/*** Created by sa…

APPLE STORE

直接在设置中,使用查看APPLE ID是无法更改的,现在必须要有所在区域的信用卡信息,支付方式无法像以前一样选择“无”。 查询后发现,有人说icloud3.0,即这个旧版的可以进行更改,于是下载。 但发现一个问题,输…

vue项目打包后文本溢出代码消失问题

补充 https://www.cnblogs.com/richard1015/p/8526988.html vue webpack 打包编译-webkit-box-orient: vertical 后消失 解决方案 optimize-css-assets-webpack-plugin这个插件的问题 注释掉webpack.prod.conf.js中下面的代码 new OptimizeCSSPlugin({cssProcessorOptions: c…

前端图片canvas,file,blob,DataURL等格式转换

最近用到一些图片相关的操作,记录一下笔记。 将file转化成base64 场景: 获取到一个file类型的图片,如果直接在html中预览?这里就是利用html5的新特性,将图片转换为Base64的形式显示出来。有两种方法: 方法…

java创建异步多线程_Java创建多线程异步执行实现代码解析

实现Runable接口通过实现Runable接口中的run()方法public class ThreadTest implements Runnable {public static void main(String[] args) {Thread thread new Thread(new ThreadTest());thread.start();}Overridepublic void run() {System.out.println("Runable 方式…

Java中的状态设计模式–示例教程

状态模式是行为设计模式之一 。 当对象根据其内部状态更改其行为时,将使用状态设计模式。 如果必须根据对象的状态更改其行为,则可以在对象中使用状态变量,并使用if-else条件块根据状态执行不同的操作。 状态模式用于通过上下文和状态实现提…

JS 循环遍历 总结

一、循环遍历语句 for...in... (ES5) 语法:javascript for(keys in obj){}适用:遍历对象说明:   1.keys表示obj对象的每一个键值对的键(键名),所有循环中,需要使用obj[keys]来取到每一个值。 …

java之平台无关

java虚拟机是执行字节码文件(.class)的虚拟机进程。 java源程序(.java)被编译器编译成------>字节码文件(.class),然后字节码文件,将由java虚拟机,解释成------>机器码&#x…

适用于ActiveMQ 5.9的Apache Camel Broker组件

将Apache Camel嵌入ActiveMQ代理可以为使用Camel的集成功能扩展消息代理提供极大的灵活性。 Apache Camel路由的另一个好处是,如果使用activemq组件 ,则可以避免远程连接到ActiveMQ的序列化和网络开销。 关于Apache ActiveMQ真正伟大的事情之一是&#x…

java rpg对战_RpgGame.java

import java.util.Scanner;public class RpgGame {public static void main(String[] args) {System.out.println("--------------------亲爱的勇士欢迎来到文字世界--------------------");System.out.println("--------------------这是一个充斥着危险的世界&…

hive基本操作与应用

通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词频统计,结果放在表word_count里 查看统计结果 转载于:https://www.cnblogs.com/cairuiqi/p/9048256.html

python - classs内置方法 solt

solt # __solt__ # 是一个类变量,变量值可以是列表、元组或者是可迭代对象,也可以是一个字符串 # (以为这所有实例只有一种数据属性) # # 作用:(为了节省内存空间,减少过多的实例属性所占用的内存空间) # 优点: # 1.使用_solt__以后,实例的__dict__属性被去除,从而达到节省…

如何优雅的链式取值之 MayBe 函子

本文基于 如何优雅地链式取值 可能有人之前看过我写的关于函数式编程的东西,也有人看过这一篇文章。由于我还是学生,开发经验相对较少,所以对于函数式编程如何应用存在一些疑惑。之前也问过面试官,说是实际开发中用的比较少&#…

Jackson中的自定义反序列化器和验证

tl; dr:将输入验证添加到Jackson中的自定义json解串器很重要。 在RHQ中,我们在几个地方使用了Json解析-直接在as7 / Wildfly插件中,或者通过RESTEasy 2.3.5间接在REST-api中使用,已经很繁重了。 现在,我们有一个bean…