快速构建H5单页面切换骨架
在Web App和Hybrid App横行的时代,为了拥有更好的用户体验,单页面应用顺势而生,单页面应用简称`SPA`,即Single Page Application,就是只有一个HTML页面的应用程序,应用中所有的视图都包含在这个HTML页面中,并通过JavaScript控制相关视图的显示和隐藏,这种模式可以让用户在Web App感受Native App的速度和流畅。本篇文章的目的就是教你如何来快速的构建一个H5单页面切换骨架。
页面设计
在构建SPA应用时,首先要确定你的应用需要包含哪些视图,在这里,为了能够说明问题,我们只需要构建三个视图,即 首页、列表页面和列表详情页面。 这三个页面的逻辑关系是:
- 程序启动,默认进入首页
- 点击首页的按钮切换到列表页面
- 点击列表页面的按钮切换到列表详情页面
- 点击返回按钮或物理返回键能够回到上一页。
首先我们来看一下核心的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);
以上便是单页面切换的基本思路,对应的完整示例代码已上传至 Github: https://github.com/git-onepixel/h5spa, 你可以下载完整代码进行调试和学习,如果需要查看效果演示,请点击或使用微信扫一扫下面的二维码进行访问:

原创发布 @一像素 2016.01
快速构建H5单页面切换骨架的更多相关文章
- 快速构建H5单页面切换应用
在Web App和Hybrid App横行的时代,为了拥有更好的用户体验,单页面应用顺势而生,单页面应用简称`SPA`,即Single Page Application,就是只有一个HTML页面的应用 ...
- H5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...
- 详细解剖大型H5单页面应用的核心技术点
项目 Xut.js 阐述下开发中一个比较核心的优化技术点,这是一套平台代码,并非某一个插件功能或者框架可以直接拿来使用,核心代码大概是6万行左右(不包含任何插件) .这也并非一个开源项目,不能商业使用 ...
- H5单页面架构:requirejs + angular + angular-route
说到项目架构,往往要考虑很多方面: 方便.例如使用jquery,必然比没有使用jquery方便很多,所以大部分网站都接入类似的库: 性能优化.包括加载速度.渲染效率: 代码管理.大型项目需要考虑代码的 ...
- 详解H5中的history单页面,手动实现单页面开发,细说h5单页面原理
就目前来看,前端的单页面开发占了很大一部分,一方面无刷新的切换增强了体验,并且浏览器记录依然存在,前进后退都没问题,在之前我们通地址栏中的hash改变来触发onhashchange方法来实现单页面应用 ...
- H5单页面架构:自定义路由 + requirejs + zepto + underscore
angular优点: 强大的数据双向绑定 View界面层组件化 内置的强大服务(例如表单校验) 路由简单 angular缺点: 引入的js较大,对移动端来说有点吃不消 语法复杂,学习成本高 backb ...
- H5单页面架构:backbone + requirejs + zepto + underscore
首先,来看看整个项目结构. 跟上一篇angular类似,libs里多了underscore和zepto.三个根目录文件: index.html:唯一的html main.js:requirejs的配置 ...
- h5单页面布局
前段时间做了一个PC端单页面应用 GitHub因为项目开始的比较仓促,加上本人前端经验特别少,虽然项目大体完成了,但是页面布局确成立它的硬伤...为了填补心里落差,专门做了一个h5的单页面布局,代码很 ...
- 快速了解SPA单页面应用
简要 SPA单页网页应用程序这个概念并不算新,早在2003年就已经有在讨论这个概念了,不过,单页应用这个词是到了2005年才有人提出使用,SPA的概念就和它的名字一样显而易懂,就是整个网站不再像传统的 ...
随机推荐
- Virtual Box配置CentOS7网络(图文教程)
之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...
- javascript动画系列第三篇——碰撞检测
前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...
- css-父标签中的子标签默认位置
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- svn 常用命令总结
svn 命令篇 svn pget svn:ignore // 查看忽略项 svn commit -m "提交说明" // 提交修改 svn up(update) // 获取最新版本 ...
- 旺财速啃H5框架之Bootstrap(一)
接下来的时间里,我将和大家一起对当前非常流行的前端框架Bootstrap进行速度的学习,以案例的形式.对刚开始想学习Bootstrap的同学而找不着边的就很有帮助了.如果你想详细的学习Bootstra ...
- 代码的坏味道(22)——不完美的库类(Incomplete Library Class)
坏味道--不完美的库类(Incomplete Library Class) 特征 当一个类库已经不能满足实际需要时,你就不得不改变这个库(如果这个库是只读的,那就没辙了). 问题原因 许多编程技术都建 ...
- Autofac - MVC/WebApi中的应用
Autofac前面写了那么多篇, 其实就是为了今天这一篇, Autofac在MVC和WebApi中的应用. 一.目录结构 先看一下我的目录结构吧, 搭了个非常简单的架构, IOC(web), IBLL ...
- 分布式学习系列【dubbo入门实践】
分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...
- 屌丝giser成长记-大学篇
作为一名屌丝giser的我,刚接触gis专业是2007年的大一,好悲催,当时gis这个专业是被调剂的,我压根都不知道gis为何物,那时候gis冷门的一逼,报名这个专业的寥寥无几.记得那时候得知被调剂到 ...
- Linux环境下常见漏洞利用技术(培训ppt+实例+exp)
记得以前在drops写过一篇文章叫 linux常见漏洞利用技术实践 ,现在还可以找得到(https://woo.49.gs/static/drops/binary-6521.html), 不过当时开始 ...