利用hash构建HTML切换
在Web App和Hybrid App横行的时代,为了拥有更好的用户体验,单页面应用顺势而生,单页面应用简称`SPA`,即Single Page Application,就是只有一个HTML页面的应用程序,应用中所有的视图都包含在这个HTML页面中,并通过JavaScript控制相关视图的显示和隐藏,这种模式可以让用户在Web App感受Native App的速度和流畅。本篇文章的目的就是教你如何来快速的构建一个H5单页面切换骨架。
一、 页面设计
在构建SPA应用时,首先要确定你的应用需要包含哪些视图,在这里,为了能够说明问题,我们只需要构建三个视图,即 首页、列表页面和列表详情页面。 这三个页面的逻辑关系是:
(1)程序启动,默认进入首页
(2)点击首页的按钮切换到列表页面
(3)点击列表页面的按钮切换到列表详情页面
(4)点击返回按钮或物理返回键能够回到上一页。
首先我们来看一下核心的HTML代码:
<body>
<div class="pageview" style="background: #3b76c0" id="-main-view">
<h3>首页</h3>
<div title="-list-view" class="right-arrow"></div>
</div>
<div class="pageview" style="background: #58c03b;display: none" id="-list-view">
<h3>列表页面</h3>
<div class="left-arrow"></div>
<div title="-detail-view" class="right-arrow"></div>
</div>
<div class="pageview" style="background: #c03b25;display: none" id="-detail-view">
<h3>列表详情页面</h3>
<div class="left-arrow"></div>
</div>
</body>
class=`pageview`的div容器所包含的就是一个独立的视图页面,在body中共有3个这样的div,需要注意的是,第2、3个div都设置了style=`display:none`,唯独第1个视图没有设置,这样做的目的就是让程序启动时默认显示首页。
在这段代码中,用一个通用的CSS类来描述每一个视图的样式以及切换效果,这个类就是`pageview`, 我们先看看pageview是如何定义的:
.pageview{
position: absolute;
left: 0;
top:0;
width: 100%;
height: 100%;
overflow: hidden;
-webkit-transition: 0.4s ease-out -webkit-transform;
}
在这里,视图页面需要设置成绝对定位,并且和父容器等宽等高,这样视图才能够平滑的进行切换,另外还需要设置页面切换的过渡效果,我们使用CSS3的transition属性, 具体的参数就不在这里做过多的讲解了,大家应该都明白的。这个样式类所产生的效果是:当改变-webkit-transform的值时,页面会以样式中定义的过渡效果进行平移,持续时间是0.4s. 到此为止,主要的页面设计已经完成了。
二、逻辑控制
要实现页面切换,就要控制两个页面同时平移,即当前页面不断的离开屏幕,新的页面不断的进入屏幕。为了方便描述,我们把原来的页面叫做`currentView`,把新的页面叫做`applyView`,即申请进入的视图。如果用transform来描述的话,currentView 需要从原来的0% 平移到-100%,即页面向左平移了一个页面宽度的距离,与此同时,appyView需要从原来的100% 平移到0%,刚好占领currentView原来的位置,当然在平移之前,我们需要设置好currentView和applyView的初始位置,分别需要设置成0%和100%。
//页面向左平移
var currentViewStart = "translateX(0%)", //currentView初始位置
applyViewStart = "translateX(100%)", //applyView初始位置
currentViewEnd = "translateX(-100%)",//currentView的最终位置
applyViewEnd = "translateX(0%)"; //applyView最终位置 //页面向右平移
if (direction == "right") {
currentViewStart = "translateX(0%)";
applyViewStart = "translateX(-100%)";
currentViewEnd = "translateX(100%)";
applyViewEnd = "translateX(0%)"
}
我们知道,通过JS操作就需要获取页面的DOM对象,为了减少DOM的查询,在页面加载时,我们将所有需要用到的页面对象一次性查询出来,并以键值对的形式存储到Map对象中,当需要使用时,只需要根据key来获取即可。
//初始化执行
initViewPool:function(){
var views = document.querySelectorAll(".pageview");
//通过call使用数组的forEach来遍历NodeList
Array.prototype.forEach.call(views,function(item){
//viewPool是一个全局对象
viewPool[item.id] = item; //将DOM的id作为键
});
},
下面我们将通过JS来控制页面的切换效果:
//获取当前页面的DOM对象
var currentView = viewPool[currentViewId];
//获取新页面的DOM对象
var applyView = viewPool[pageId]; //设置新页面的初始位置
applyView.style.webkitTransform = applyViewStart;
//设置当前页面的初始位置
currentView.style.webkitTransform = currentViewStart; //设置新页面显示
applyView.style.display = ""; var t1 = setTimeout(function(){
//当设置最终位置时,页面就会以过渡效果平移到最终位置
applyView.style.webkitTransform = applyViewEnd;
currentView.style.webkitTransform = currentViewEnd;
},200); var t2 = setTimeout(function(){ //400ms后,页面平移结束,设置currentView为隐藏
currentView.style.display = "none";
//将新页面设置为当前页面
currentViewId = pageId; if (direction === 'left'){
window.location.hash = currentViewId.substring(1);
} window.clearTimeout(t1);
window.clearTimeout(t2);
},600);
在这里有一个重要的操作就是:一定要将设置最终位置的操作放到定时器中,即t1, 这是因为当页面被设置了初始位置后,需要一定的时间来`渲染`这个样式,第2个定时器是为了等待动画执行完毕后进行相关的操作,比如设置当前页面,设置hash,清除定时器等。当这段代码被执行时,页面就会以设定的效果进行平滑的移动,最终,当前页面被隐藏,新页面被设置为当前页面显示到屏幕中央,这样就完成了一次单页面切换效果。
三、支持物理键返回
既然是单页面切换,就不得不提另外一个问题,那就是物理返回键操作。其实,单页面切换只是页面的显示和隐藏操作,仅此而已,并不是真正意义上的hash跳转,而物理键返回实际上是监听浏览器的hash变化,因此为了让单页面能够支持物理键返回操作,我们需要模拟浏览器的hash变化,即当一个新页面进入时,给当前地址加上一个#hash 的标识,当点击物理返回键的时候,这个hash值会发生变化(回退到上一个hash),与此同时也会触发一个hashchange事件,当监听到hash变化时,我们就通过JS切换上一个hash对应的页面,这样就实现了物理返回键的效果。
if (direction === 'left'){
//当进入到新页面时,设置当前hash的值为当前页面的id
window.location.hash = currentViewId.substring(1);
}
监听hash变化的处理:
var that = this;
window.addEventListener("hashchange", function () { //当点击返回键时,hash会回退到上一页的hash值
//获取上一页的hash值,并转化为对应view的id
var id = window.location.hash.replace("#", "-"); // 判断当前页面不是首页,
// 并且触发的浏览器的`back`操作,即点击返回键,因为页面前进的时候也会发生hash变化
if (currentViewId != "-main-view" && id != currentViewId) {
id = id || "-main-view"; //如果上一页是首页,则hash为空,这时需要补上对应的id
//调用forward方法从当前页面切换到上一页
that.forward(id, "right");
}
}, false);
利用hash构建HTML切换的更多相关文章
- React初步学习-利用React构建个人博客
React初步学习-利用React构建个人博客 用React和Webpack写了一个很简单的个人博客,主要是想要熟悉一下react中各种基本基本属性及方法的使用.在构建过程中碰到不少问题,通过阅读官方 ...
- 利用Dockerfile构建一个基于centos 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像
Dockerfile内容如下: FROM centos MAINTAINER Victor ivictor@foxmail.com WORKDIR /root RUN rm -f /etc/yum.r ...
- 利用node构建本地服务
利用node构建本地服务 首先安装下node.js,地址为https://nodejs.org/en/,然后安装npm. node.js的中文api地址http://nodeapi.ucdok.com ...
- Spark:利用Eclipse构建Spark集成开发环境
前一篇文章“Apache Spark学习:将Spark部署到Hadoop 2.2.0上”介绍了如何使用Maven编译生成可直接运行在Hadoop 2.2.0上的Spark jar包,而本文则在此基础上 ...
- [Gradle] 在 Eclipse 下利用 gradle 构建系统
转载自:http://www.ibm.com/developerworks/cn/opensource/os-cn-gradle/ 构建系统时候常常要用到 Ant, Maven 等工具,对于初学者 ...
- 利用 vue-cli 构建一个 Vue 项目
一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...
- springboot+mybatis-puls利用swagger构建api文档
项目开发常采用前后端分离的方式.前后端通过API进行交互,在Swagger UI中,前后端人员能够直观预览并且测试API,方便前后端人员同步开发. 在SpringBoot中集成swagger,步骤如下 ...
- 利用openssl构建根证书-服务器证书-客户证书
利用openssl构建根证书-服务器证书-客户证书 OpenSSL功能远胜于KeyTool,可用于根证书,服务器证书和客户证书的管理 一.构建根证书 1.构建根证书前,需要构建随机数文件(.rand) ...
- [转]利用Docker构建开发环境
利用Docker构建开发环境 Posted by makewonder on 2014 年 4 月 2 日 最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境, ...
随机推荐
- notepad快捷键总结
notepad快捷键总结 常用快捷键: 快捷键 功能1.Ctrl-D 复制当前行2.Ctrl-L 删除当前行3.Ctrl-T 把当前行和前面一行调换位置4.F11 切换全屏模式5.Ctrl-Shft- ...
- Redis 搜索引擎优化
场景 大家如果是做后端开发的,想必都实现过列表查询的接口,当然有的查询条件很简单,一条 SQL 就搞定了,但有的查询条件极其复杂,再加上库表中设计的各种不合理,导致查询接口特别难写,然后加班什么的就不 ...
- redis实现自动输入完成(八)
1. 介绍 当我们在京东商城的搜索框,输入想要搜索的内容,比如你想要搜索"热水瓶",刚输入一个"热"字,就会出现一个下拉框,列出了很多以"热" ...
- 《FTL之垃圾回收、写放大和OP 》总结
来自 http://www.ssdfans.com/?p=1840: 写放大WA: 对空盘来说(未触发GC),写放大一般为1,即Host写入多少数据,SSD写入闪存也是多少数据量(这里忽略SSD内部数 ...
- 在firefox安装Selenium IDE
1.打开地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/: 2.点击Add to Firefox: 3.打开Firefox ...
- 无法从U盘启动的解决方案
联想台式机无法从U盘启动的解决方案 F1进入lenovo bios 选择 StartUp 选项卡 1) 发现 USB FDD 已处于第一项,再把 USB Key 调到启动第二项 2) 把 boot m ...
- 002-jdk10安装
下载地址: 1.百度云下载地址.(当然也可以官网下载,都一样) 地址:https://pan.baidu.com/s/13oZh_5tXb_Xadg9f-y2Idw 密码:a9h8 安装jdk: 2. ...
- NC审批流开发流程
1.新建的是数据库表结构中一定要有 [审批人. 制单人. ...
- NIO 02 (转)
本文转自:http://weixiaolu.iteye.com/blog/1479656 SelectionKey.OP_ACCEPT // 服务端监听,并注册OP_ACCEPT事件后,就已准备好接受 ...
- GRUB2 分析 (四)
接上一篇 kernel.img由startup.S以及一堆c文件编译而成.这是一个ELF格式的文件.(其实前面的boot.img. diskboot.img.lzma_decompress.img本来 ...