使用《UrlHash/锚点》解决移动设备中的单页面应用的物理[返回键]带来的困扰
来源:互联网 发布:热血沙尘 全套源码 编辑:程序博客网 时间:2024/06/05 07:44
事由
今天同事在开发WebApp的时候,遇到一个小问题,就是移动设备,准确来说是安卓设备中的物理返回键,会直接忽略一些页面效果,直接跳转回上一个页面。但是同事的这个页面包含了几个层的点击显示,在列表里点击会切换层显示详情。但是如果点击物理返回键之后,会直接略过列表,跳回上一个页面。
设想中的效果
[OrderPage] → <ALinkClick> → [ListPage] → <ListClick> → [ItemDetails] → <VirtualBackButtonClick> → [ListPage] → <VirtualBackButtonClick> → [OrderPage]
但实际遇到的问题
[OrderPage] → <ALinkClick> → [ListPage] → <ListClick> → [ItemDetails] → <PhysicalBackButtonClick> → [OrderPage]
中间略过了[ListPage],这样是完全违背了使用习惯的,而且也并不可能强迫用户只用页面中的虚拟返回键,所以就尝试了一下,给同事提供了一个解决这个问题的思路,这里稍微记录一下。
核心
UrlHash/锚点 + window.onhashchange事件。
解决思路
首先,同事需要实现的效果,从原理上来说,就是点击一个层A(或者说是LIst/Ul中的一个节点),触发一个点击事件,然后展示一个层B,层B中的内容为层A对象物品的详情页。
然后,思路明白了就好说了,就是点击返回按钮的时候隐藏层B。从百度中我们可以知道,如果通过PhoneGap之类的封装过的WebAPP,确实是可以捕获物理返回键的点击事件的。但是我们是网页,没做任何封装,同样,如果是微信WebAPP的话,也是应该没办法捕获的。
那么解决方案就寄望于Url中带参了。再从百度中可以了解到,Url中出现#有两种作用,一种是跳转到指定锚点,另一种就是传递参数。我们解决当前问题就是用的第二种作用,配合HTML5中新增的window.onhashchange事件,和#会改变浏览器的访问历史,增加一个访问历史,使浏览器中的返回键会返回到上一个位置。这就得以比较顺利的解决物理返回键的问题了。
参考他人Blog文章《URL中出现#号》,非常感谢。
测试代码
因为比较偷懒,div层的点击事件就直接写死在html中了。
css:
<span style="font-family:Microsoft YaHei;font-size:18px;">div { width: 200px; height: 100px; display: none; font-size: 5em; }</span>
html:
<span style="font-family:Microsoft YaHei;font-size:18px;"><div id="div1" onclick="divClick('div2')" style="background-color: yellow;display: block;">Div1</div><div id="div2" onclick="divClick('div3')" style="background-color: red;">Div2</div><div id="div3" onclick="divClick('div4')" style="background-color: green;">Div3</div><div id="div4" onclick="divClick('div1')" style="background-color: blue;">Div4</div></span>
js:
<span style="font-family:Microsoft YaHei;font-size:18px;">//给页面绑定hashchange事件 window.onhashchange = function(){ var hashCode = location.hash; var _id = hashCode.substr(1);//去掉#,获取后面带的参数 divchange(_id); }; //div点击事件 function divClick(_id){ location.href = "#"+_id; } //div切换触发 function divchange(_id){ div1.style.display = 'none'; div2.style.display = 'none'; div3.style.display = 'none'; div4.style.display = 'none'; document.getElementById(_id).style.display = 'block'; }</span>
结果
通过以上代码,可以通过点击切换不同的div显示,具体显示由点击后传入的锚点带的参数决定。如果想进一步复杂,甚至可以组织成复杂的锚点#带参,如固定5个字符长度的参数,每个字符的字母或者数字表示特定的层的显示或隐藏之类的。当然,上面代码也有非常不足的地方,例如,一开始的没有锚点#的时候,或者有错误锚点#的时候,又怎么处理。不过这些都是些不影响解决主要功能需求的小地方了,实际用上的时候再注意补上就OK啦。
附件
完整测试代码:点击打开链接
- 使用《UrlHash/锚点》解决移动设备中的单页面应用的物理[返回键]带来的困扰
- 使用《UrlHash/锚点》解决移动设备中的单页面应用的物理[返回键]带来的困扰
- 解决Myeclipse ctrl+h带来的困扰
- FLex中的this关键字带来的困扰
- redhat带来的困扰
- 单页面应用的游览器返回键禁止问题
- 宽带安装带来的困扰
- http_build_query函数带来的困扰
- http_build_query函数带来的困扰
- 解决OnsenUI单页面应用物理回退问题
- 页面缓存的困扰
- PHP的session阻塞机制带来的单页面多ajax请求阻塞的解决
- 使用pushState实现微信“返回”按钮控制单页应用页面的无刷新跳转
- Hibernate的SaveOrUpdate方法带来的困扰
- UTF-8 BOM带来的困扰
- OpenCV版本问题带来的困扰
- ScrollView代码布局(SnapKit)带来的困扰
- 正则表达式反斜杠带来的困扰
- linux的僵尸进程和孤儿进程及解决方法
- java线程
- C#学习笔记 基本数据类型
- android学习之使用AIDL实现进程间的通讯
- Linux 键盘模拟测试
- 使用《UrlHash/锚点》解决移动设备中的单页面应用的物理[返回键]带来的困扰
- linux新装的系统下su命令不能使用的解决办法
- Opencv (Opencv2)结合MFC学习数字图像处理---显示图片
- 关于偏好设置文件的使用
- jdbcType与javaType的对应关系
- OO模式-Proxy模式<一>静态代理
- HDU 5521 Meeting 最短路
- 经典SQL语句大全
- java类与继承