webapp应用--模拟电子书翻页效果
前言:
现在移动互联网发展火热,手机上网的用户越来越多,甚至大有超过pc访问的趋势。所以,用web程序做出仿原生效果的移动应用,也变得越来越流行了。这种程序也就是我们常说的单页应用程序,它也有一个英文缩写,叫SPA; 它最大的特点就是可以利用前端技术做出跨平台的移动应用。技术难点在于理解虚拟页面与物理页面之间的变换关系。一个偶然的机会,我由php程序员转为web前端开发,主攻javascript编程,不知不觉,已经快两年了。一直有一种想写一个webapp应用框架的冲动,但是各种原因,终究没有付出实践。于是打算从做一个简单的webapp应用开始,万事开头难,今天就搭一个简单的界面。
HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>单页应用</title>
<link rel="stylesheet" href="css/common.css" type="text/css"/>
</head>
<body>
<div class="container">
<header>
<h3>sameple test </h3>
</header>
<ul class="root">
<li class="page">1</li>
<li class="page">2</li>
<li class="page">3</li>
<li class="page">4</li>
<li class="page">5</li>
<li class="page">6</li>
<li class="page">7</li>
<li class="page">8</li>
<li class="page">9</li>
<li class="page">10</li>
</ul>
<div class="left">prev</div>
<div class="right">next</div>
<footer>
<h4>(c)2015 by ouyangli</h4>
</footer>
</div>
</body>
<script type="text/javascript" src="lib/core.js"></script>
</html>
css:
ul , li {
margin:;
padding:;
list-style: none;
}
h3,h4,p {
margin:;
padding:;
}
header {
position: absolute;
width:100%;
top:;
left:;
z-index:;
} header h3 {
text-align: center;
height: 3em;
line-height: 3em;
border-bottom: 1px solid green;
} .container {
position: absolute;
width :320px;
height: 480px;
left:320px;
top:2em;
} .root {
position: absolute;
width :100%;
height: 100%;
top :;
left:;
overflow:hidden;
-webkit-perspective:;
-webkit-user-select: none;
-webkit-transform-style:preserve-3d;
} .page {
position: absolute;
width: 318px;
height: 100%;
overflow: hidden;
border:1px solid green;
} .left {
left :2px;
}
.right {
right:2px;
} .left,.right {
position: absolute;
top:45%;
width:3em;
height: 3em;
line-height: 3em;
text-align: center;
border-radius: 15%;
border:1px dashed blue;
} .left:hover,.right:hover {
background-color: #33ff44;
cursor:pointer;
} footer {
position: absolute;
width: 100%;
bottom:;
} h4 {
height: 3em;
line-height: 3em;
text-align: center;
border-top: 1px solid green;
}
以上源码将会在页底提供打包下载,这里贴出中间过程,只是想让大家能明白,我是怎么一步一步把这个程序写出来的。如果有疑问的地方就给我留言好了,我会尽量回复。
演示地址:http://runjs.cn/detail/o4ql6f6a
细心的话,你会发现左上角有一个“乱码”,其实那是因为所有的页面都堆叠在一起,造成页数看不清了。这正是我们接下来要解决的问题之一。
js:
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d('+width+'px, 0, 0)';
} //把除1以外的页堆在右边
while(--len){
setpost(pages[len]);
}
}());
好了,现在看起来仅管还是很丑,但是至少已经符合我预期的样子了。在这里我把第一页已外的页面全部摆到了屏幕的右边,你看不到它们。这样做的目的是要模拟手机上的翻页效果。接下来,就要实现这个非常令人期待的滑动翻页效果。现在该javascript发挥威力的时候了。这是一个简单的应用,我尽量把所有的js写在core.js中,并采用最普通的函数式编程。
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d('+width+'px, 0, 0)';
} //把除1以外的页堆在右边
while(--len){
setpost(pages[len]);
}
}()); //控制逻辑
;(function(){
//这里直接使用了新的api,因为移动应用可以这样任性。
var pages = document.querySelectorAll('li');
//左右翻页按钮
var left = document.querySelector('.left');
var right = document.querySelector('.right');
//取得所有的子页面
var pagesLen = pages.length-1; //标记当前页面
var currIndex = 0; //移动页面
var move = function(index,pos){
var width = 320 * pos;
var page = pages[index];
page.style.transform = 'translate3d('+width+'px, 0, 0)';
} //向左翻页
var toLeft = function(){ if(currIndex!==pagesLen){
move(currIndex,-1);
move(++currIndex,0);
}
} //向右翻页
var toRight = function(){
if(currIndex!==0){
move(currIndex,1);
move(--currIndex,0);
}
} //监听动作
left.onclick = function(){
toLeft();
} right.onclick = function(){
toRight();
} }())
现在我们的程序可以左右翻页了,不过除了页码发生了变化之外,用户好像感觉不到有翻页的效果。左右翻页按钮的作用与我们期望的效果不一致,所以初始化时,把页面堆在右边其实是不太好的,改为左边会更好一些。嗯,还要继续完善。
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d(-'+width+'px, 0, 0)';
} //把除1以外的页堆在左边
while(--len){
setpost(pages[len]);
}
}()); //控制逻辑
;(function(){
//这里直接使用了新的api,因为移动应用可以这样任性。
var pages = document.querySelectorAll('li');
//左右翻页按钮
var left = document.querySelector('.left');
var right = document.querySelector('.right');
//取得所有的子页面
var pagesLen = pages.length-1; //标记当前页面
var currIndex = 0; //移动页面
var move = function(index,pos){
var width = 320 * pos;
var page = pages[index];
page.style.transform = 'translate3d('+width+'px, 0, 0)';
page.style.transitionDuration = '300ms';
} //上一页
var toLeft = function(){
if(currIndex >0){
move(currIndex,-1);
move(--currIndex,0);
}
} //下一页
var toRight = function(){
if(currIndex < pagesLen){
move(currIndex,1);
move(++currIndex,0);
}
} //监听动作
left.onclick = function(){
toLeft();
} right.onclick = function(){
toRight();
} }())
现在终于看起来像是在翻页的样子了,不过呢,我们在手机上操作的时候,是可以滑动翻页的,这个效果自然也要支持才行。我们先在pc上用鼠标拖动来模拟这一个过程,等逻辑跑通后,再加入触摸事件即可。
继续下一步之前,我们先小结一下:
首先在初始化代码时,顺道把所有不可见的页面全部堆叠到左边,放在左边的原因是因为我们习惯右边的按钮作为下一页,所以这样摆放,实现起来最简单,我当然要选择最有利于我编码的方式来摆放啦。其次呢,每一次翻页,其实都要移动两个页面。拿点击下一页按钮来说,首先要把当前页移动到不可见的屏幕右边,然后把上一页移到屏幕中间来。上一页的过程正好与之相反。我们发现,点击翻页和滑动翻页,其实都会调用相同的功能。所以在这里可先抽出公共方法,方便代码复用。
接下来,我们实现鼠标拖动翻页的效果。
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d(-'+width+'px, 0, 0)';
} //把除1以外的页堆在左边
while(--len){
setpost(pages[len]);
}
}()); //控制逻辑
;(function(){
//这里直接使用了新的api,因为移动应用可以这样任性。
var pages = document.querySelectorAll('li');
//左右翻页按钮
var left = document.querySelector('.left');
var right = document.querySelector('.right');
//取得所有的子页面
var pagesLen = pages.length-1;
//屏宽
var screenWidth = 320; //标记当前页面
var currIndex = 0; //标记是否触发滑动
var isTouch = false;
//记录当前位置
var axis = {
x:0,
y:0
} //移动页面
var move = function(index,width,time){
var page = pages[index];
page.style.transform = 'translate3d('+width+'px, 0, 0)';
page.style.transitionDuration = time+'ms';
} //上一页
var toLeft = function(){
if(currIndex >0){
move(currIndex,-screenWidth,300);
move(--currIndex,0,300);
}
} //下一页
var toRight = function(){
if(currIndex < pagesLen){
move(currIndex,screenWidth,300);
move(++currIndex,0,300);
}
} //监听动作
left.onclick = function(){
toLeft();
} right.onclick = function(){
toRight();
} document.addEventListener('mousedown',function(e){
isTouch = true;
axis.x = e.clientX;
axis.y = e.clientY;
}); document.addEventListener('mousemove',function(e){
if(isTouch){
var distance = e.clientX - axis.x;
if(distance>0){
//next
//此时需要看到实时移动效果,所以时间为0
move(currIndex,distance,0);
//当前页与上一页之间总是相差一个屏宽
move(currIndex+1,distance-screenWidth,0);
}else{
//prev
move(currIndex,distance,0);
move(currIndex-1,screenWidth+distance,0); }
}
}); document.addEventListener('mouseup',function(e){
isTouch = false;
}); }())
这一步我们已经实现了拖动滑页效果,但是感觉怪怪的,对比一下手机上的滑动翻页效果发现,真机上只要我们滑动一定距离之后,页面就自动翻过去了,而不是要我们从一边一直滑到另一边,这样也太不实际了,而且如果我们只滑了一点距离,那么页面会自动归位,也就是常说的反弹效果。要实现这些也不难,我们继续完善代码。
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d(-'+width+'px, 0, 0)';
} //把除1以外的页堆在左边
while(--len){
setpost(pages[len]);
}
}()); //控制逻辑
;(function(){
//这里直接使用了新的api,因为移动应用可以这样任性。
var pages = document.querySelectorAll('li');
//左右翻页按钮
var left = document.querySelector('.left');
var right = document.querySelector('.right');
//取得所有的子页面
var pagesLen = pages.length-1;
//屏宽
var screenWidth = 320;
//反弹时间
var time = 300;
//滑动距离
var distance=0;
//标记当前页面
var currIndex = 0; //标记是否触发滑动
var isTouch = false;
//记录当前位置
var axis = {
x:0,
y:0
} //移动页面
var move = function(index,width,time){
var page = pages[index];
page.style.transform = 'translate3d('+width+'px, 0, 0)';
page.style.transitionDuration = time+'ms';
} //上一页
var toLeft = function(){
if(currIndex >0){
move(currIndex,-screenWidth,time);
move(--currIndex,0,time);
}
} //下一页
var toRight = function(){
if(currIndex < pagesLen){
move(currIndex,screenWidth,time);
move(++currIndex,0,time);
}
} //监听动作
//prev
left.onclick = function(){
toLeft();
}
//next
right.onclick = function(){
toRight();
} document.addEventListener('mousedown',function(e){
isTouch = true;
axis.x = e.clientX;
axis.y = e.clientY;
}); document.addEventListener('mousemove',function(e){
if(isTouch){
distance = e.clientX - axis.x;
if(distance>0){
//next
if(currIndex<pagesLen){
//此时需要看到实时移动效果,所以时间为0
move(currIndex,distance,0);
//当前页与上一页之间总是相差一个屏宽
move(currIndex+1,distance-screenWidth,0);
}
}else{
if(currIndex>0){
//prev
move(currIndex,distance,0);
move(currIndex-1,screenWidth+distance,0);
}
}
}
}); document.addEventListener('mouseup',function(e){
isTouch = false;
//反弹条件
var band = Math.ceil(screenWidth * 0.3);
//next
if(distance >0 && currIndex < pagesLen){
if(distance > band){
toRight();
}else{
//滑动距离太小,页面反弹
move(currIndex,0,time);
move(currIndex+1,-screenWidth,time);
}
return;
}
//prev
if(distance < 0 && currIndex > 0){
if(-distance > band){
toLeft();
}else{
//反弹
move(currIndex,0,time);
move(currIndex-1,screenWidth,time);
}
}
}); }())
最后发现有一点小问题,滑动之后再点翻页按钮,乱套了。仔细分析之后,找出了问题所在,松手时的移动距离不应该用滑动时的最后距离,所以修复很容易。
//初始化
;(function(){
var pages = document.querySelectorAll('li');
var width = 320;
var len = pages.length;
var setpost = function(element){
element.style.transform = 'translate3d(-'+width+'px, 0, 0)';
} //把除1以外的页堆在左边
while(--len){
setpost(pages[len]);
}
}()); //控制逻辑
;(function(){
//获取所有页面
var pages = document.querySelectorAll('li');
//左右翻页按钮
var left = document.querySelector('.left');
var right = document.querySelector('.right');
//取得所有的子页面
var pagesLen = pages.length-1;
//屏宽
var screenWidth = 320;
//反弹时间
var time = 300; //标记当前页面
var currIndex = 0; //标记是否触发滑动
var isTouch = false;
//记录当前位置
var axis = {
x:0,
y:0
} //移动页面
var move = function(index,width,time){
var page = pages[index];
page.style.transform = 'translate3d('+width+'px, 0, 0)';
page.style.transitionDuration = time+'ms';
} //上一页
var toLeft = function(){
if(currIndex >0){
move(currIndex,-screenWidth,time);
move(--currIndex,0,time);
}
} //下一页
var toRight = function(){
if(currIndex < pagesLen){
move(currIndex,screenWidth,time);
move(++currIndex,0,time);
}
} //监听动作
//prev
left.onclick = function(){
toLeft();
}
//next
right.onclick = function(){
toRight();
} document.addEventListener('mousedown',function(e){
isTouch = true;
axis.x = e.clientX;
axis.y = e.clientY;
}); document.addEventListener('mousemove',function(e){
if(isTouch){
//滑动距离
var distance = e.clientX - axis.x;
if(distance>0){
//next
if(currIndex<pagesLen){
//此时需要看到实时移动效果,所以时间为0
move(currIndex,distance,0);
//当前页与上一页之间总是相差一个屏宽
move(currIndex+1,distance-screenWidth,0);
}
}else{
if(currIndex>0){
//prev
move(currIndex,distance,0);
move(currIndex-1,screenWidth+distance,0);
}
}
}
}); document.addEventListener('mouseup',function(e){
//松手时的移动距离
var distance = e.clientX - axis.x;
//反弹条件
var band = Math.ceil(screenWidth * 0.3);
isTouch = false;
//next
if(distance >0 && currIndex < pagesLen){
if(distance > band){
toRight();
}else{
//滑动距离太小,页面反弹
move(currIndex,0,time);
move(currIndex+1,-screenWidth,time);
}
return;
}
//prev
if(distance < 0 && currIndex > 0){
if(-distance > band){
toLeft();
}else{
//反弹
move(currIndex,0,time);
move(currIndex-1,screenWidth,time);
}
}
}); }())
到此,这个简易的移动应用就建好了。发现这其实只是搭好了一个架子,里边还有很多内容可以填。比如,给每页加点背景和文字,让页面看起来更加丰满,给标题栏加点工具图标,让它看起来更像是一个原生的apk程序。当我们双击或长按页面空白区域的时候,自动隐藏或显示翻页按钮,增加对更多浏览器的支持,增加对移动设备的支持........
可以发挥的地方太多太多了,锦上添花的事就只好交给各位了。
一步一步做下来,收获了些什么呢?总结一下:
首先要有一个清晰的思路,先确定要实现什么功能,在脑海里有一个整的印象。把UI先建起来,这一步很容易实现,在此基础上,我们就可以看到,有哪些功能需要js去做,哪些效果需要css去做。先易后难。先整体后局部。在做的过程中,一步一步的完善,扩展,优化。一开始就想着要多完美,多优化,结果只是不断的否定自己的想法。不要怕出错,前面的演示中,我们发现,每一步都有些小错误,但是只要我们的整体思路是符合预期的,修正起来就会很快,这个修错的过程,也是一次学习的机地,总结的多了,以后就可以少出错,少被坑。
效果图:
加点内容,是不是立马显得高大上了呀!
源码打包下载:https://github.com/bjtqti/swipe.git
本文系原创,如果喜欢就砸个赞吧!
webapp应用--模拟电子书翻页效果的更多相关文章
- javascript移动端 电子书 翻页效果
1.后端给一长串的纯文本 2.前端根据屏幕的高度,将文本切割为 n 页 3.使用插件 turn.js 将切割好的每页,加上翻书效果 <!DOCTYPE html> <html lan ...
- Android电子书翻页效果实现
这篇文章是在参考了别人的博客基础上,修改了其中一个翻页bug,并且加了详细注释 先看效果 其中使用了贝赛尔曲线原理,关于贝赛尔曲线的知识,推荐大家看下http://blog.csdn.net/hmg2 ...
- 6个超炫酷的HTML5电子书翻页动画
相信大家一定遇到过一些电子书网站,我们可以通过像看书一样翻页来浏览电子书的内容.今天我们要分享的HTML5应用跟电子书翻页有关,我们精选出来的6个电子书翻页动画都非常炫酷,而且都提供源码下载,有需要的 ...
- c#翻页效果
用c#和GDI+实现杂志翻页动画效果时间:2010-01-13 blog.csdn.net 周公 - 说明:以前本人参与个一个电子杂志项目,当时要求实现模拟现实生活中的杂志翻页动画效果,别人推荐了这篇 ...
- Android 实现书籍翻页效果----完结篇
By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前由于种种琐事,暂停了这个翻页效果的实现,终于在这周末完成了大部分功能,但是这里只是给出了一个基本的雏形,没有添 ...
- Android 实现书籍翻页效果----升级篇
自从之前发布了<Android 实现书籍翻页效果----完结篇 >之后,收到了很多朋友给我留言,前段时间由于事情较多,博客写得太匆忙很多细节地方没有描述清楚.所以不少人对其中的地方有不少不 ...
- Android 滑动效果高级篇(七)—— 华丽翻页效果
By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前看到像ipad上的ibook的模拟书籍翻页的特效感觉很炫,在android上也有像laputa和ireader ...
- HTML5开发的翻页效果实例
简介2010年F-i.com和Google Chrome团队合力致力于主题为<20 Things I Learned about Browsers and the Web>(www.20t ...
- 微信里经常看到的滑动翻页效果,slide
上个星期我们的产品姐姐让我帮她写个微信里经常看到的滑动翻页效果,今天抽空写了3个小demo(只写了webkit需要chrome模拟手机看 开启touch事件), 故此写个随笔. 1.demo1,整个大 ...
随机推荐
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- Azure Service Fabric 开发环境搭建
微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...
- 高大上的微服务可以很简单,使用node写微服务
安装 npm install m-service --save 使用 编写服务处理函数 // dir1/file1.js // 使用传入的console参数输出可以自动在日志里带上request id ...
- (系统架构)标准Web系统的架构分层
标准Web系统的架构分层 1.架构体系分层图 在上图中我们描述了Web系统架构中的组成部分.并且给出了每一层常用的技术组件/服务实现.需要注意以下几点: 系统架构是灵活的,根据需求的不同,不一定每一层 ...
- SQL Server 2014 新特性——内存数据库
SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...
- ExtJS 4.2 组件的查找方式
组件创建了,就有方法找到这些组件.在DOM.Jquery都有各自的方法查找元素/组件,ExtJS也有自己独特的方式查找组件.元素.本次从全局查找.容器内查找.form表单查找.通用组件等4个方面介绍组 ...
- Oracle碎碎念~2
1. 如何查看表的列名及类型 SQL> select column_name,data_type,data_length from all_tab_columns where owner='SC ...
- PHP static静态属性和静态方法
这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...
- (整理)MyBatis入门教程(一)
本文转载: http://www.cnblogs.com/hellokitty1/p/5216025.html#3591383 本人文笔不行,根据上面博客内容引导,自己整理了一些东西 首先给大家推荐几 ...