IOS设备上网页中的页面滚动效果模拟
可能咋一看不知道我说的是个啥,因为iOS本来就用这功能的啊,还模拟它干啥?先听我说下项目背景哈
我现在开发的是一个webapp,主要是用在ipad上,这个app的大小是固定大小的,为了防止触摸它出现弹性滚动,我加个句代码:
- $(document).bind('touchmove', function(e) {
- e.preventDefault();
- });
这样这个页面就被我锁死了,不会出现讨厌的弹性滚动了,再加上一些meta属性(我的blog里有这些)全屏啥的,基本上跟nativeapp无异了。
但是呢,问题出来了,里面有个div里面内容比较多,需要用到滚动条,现在的问题是,我的网页里设置这个div的overflow为scroll后,触摸这个div不能滚动了!我先试着把上面的代码注释点,发现可以滚动了,但是效果很差,没有ios自带的那种手离开后还会滚动一会的那种“刹车”的效果,于是呢,就想着自己搞一个出来,于是就写了一个jQuery插件,实现了上下左右滑动和轻拍(因为点击事件在ipad上有半秒延迟),下面会有下载地址。关于滚动效果呢,是我花了一整天时间研究出来的,觉得收获很大,所以拿出来跟大家分享下,以下是一些核心代码:
- (function show(time){
- if(!source.animation){return;}
- source.animation = window.setTimeout(function(){
- if(time > 90){ return; }
- X && $self.scrollLeft($self.scrollLeft() - ha(time,speedX) * aa );
- Y && $self.scrollTop($self.scrollTop() - ha(time,speedY) * aa );
- show(++time);
- },aa);
- })(1);
函数ha:
- function ha(x,maxSpeed){
- //return maxSpeed / x;//y = 100 / x;
- //return maxSpeed - maxSpeed / 100 * x;// y = -x + 100;
- return (1 - Math.sqrt(10000-(x-100)*(x-100)) / 100) * maxSpeed ;//y = -sqrt(10000-(x-100)2) + 100
- }
上面第一段代码的意思是在手指离开屏幕之后要执行的一个连续动画,可以看到,随着时间速度越来越慢,速度的变化由函数ha决定,一开始我用y = 1/x的速度,发现速度变化太快,动画执行完一半就基本上等于结束了,后来就是在慢慢的蹭一秒多,县的很不流畅。。然后就换,换成了第二个,y = -x + 100,这个效果好一点了,但是太流畅了。。刷一下飞好远。。用aa调整灵敏度后效果还是差强人意,于是看了半天苹果自带的效果,发现速度在由快变慢的过程中,加速度绝对值的变化程度好像是小--大--小的一个状态,于是我就试着用y = x2 - 10x(具体多少忘记了)之类的函数去试,效果还好,不过还是有点快,最后我选中了四分之一圆,这个弧度性感又均衡,在灵敏度调整为20后,终于实现了和ios相差无几的滚动效果,心里那个高兴啊。。呵呵,。
由于代码不长,就直接贴这里了,简单的API如下:
$(selecor).swipeleft(fn).swiperight(fn).swipeup(fn).swipedown(fn).tap(fn).scrollX().scrollY().scroll('xy');注意滚动和swipe会冲突,尽量避免一起使用~
jQueqy.tomTouch.js
- (function($){
- //if (!document.documentElement.ontouchstart){return;}
- var events = "touchmove,tap,swiperight,swipeleft,swipeup,swipedown";
- var proto = function($e,type,fn){
- this.$e = $e;
- this.type = type;
- this.fn = fn;
- };
- proto.prototype = {
- swipeDistance:40,
- startX:0,
- startY:0,
- tempX:0,
- tempY:0,
- startTime:undefined,
- animation:undefined,
- touchmove:function(e){
- var self = e.data;
- e = e.originalEvent;
- if (e.targetTouches.length >= 1) {
- var touch = e.targetTouches[0];
- if(self._touchmove){
- self.fn.touchmove.call(this,{
- deltaX:touch.pageX - self.tempX,
- deltaY:touch.pageY - self.tempY,
- x:touch.pageX,
- y:touch.pageY,
- tomSource:self
- });
- }
- self.tempX = touch.pageX;
- self.tempY = touch.pageY;
- }
- },
- touchstart:function(e){
- var self = e.data;
- e = e.originalEvent;
- if (e.targetTouches.length >= 1) {
- var touch = e.targetTouches[0];
- self.tempX = self.startX = touch.pageX;
- self.tempY = self.startY = touch.pageY;
- self.animation = undefined;
- self.startTime = +new Date;
- self.fn.touchstart &&
- self.fn.touchstart.call(this,{x:e.pageX,y:e.pageY,tomSource:self});
- }
- },
- touchend:function(e){
- var self = e.data;
- e = e.originalEvent;
- if (e.changedTouches.length >= 1) {
- self.animation = true;
- var touch = e.changedTouches[0]
- ,now = +new Date()
- ,dX = touch.pageX - self.startX
- ,dY = touch.pageY - self.startY
- ,AdX = Math.abs(dX)
- ,AdY = Math.abs(dY)
- ,timeD = now - self.startTime;
- if(
- (timeD < 100 && AdX < 15 && AdY < 15 && self._tap) ||
- (dX > self.swipeDistance && AdX > AdY && self._swiperight) ||
- (-dX > self.swipeDistance && AdX > AdY && self._swipeleft) ||
- (dY > self.swipeDistance && AdY > AdX && self._swipedown) ||
- (-dY > self.swipeDistance && AdY > AdX && self._swipeup)){
- self.fn.call(this,{});
- }
- var speedX = dX / timeD;
- var speedY = dY / timeD;
- //d(self.startY + "," + touch.pageY);
- self.fn.touchend &&
- self.fn.touchend.call(this,{
- x:touch.pageX,
- y:touch.pageY,
- speedX:speedX,
- speedY:speedY,
- tomSource:self
- });
- }
- },
- handle:function(){
- var self = this;
- $.each(events.split(',')
- ,function(i,item){
- if(item == self.type){
- self[ "_" + item ] = true;
- }
- });
- self.$e.bind("touchmove",self,self.touchmove);
- self.$e.bind("touchstart",self,self.touchstart);
- self.$e.bind("touchend",self,self.touchend);
- }
- };
- $.each(events.split(","),function(i,name){
- $.fn[name] = function(fn){
- var touches = new proto($(this),name,fn);
- touches.handle();
- return $(this);
- }
- });
- $.fn.touchScroll = function(direction){
- var X = /x/gi.test(direction)
- ,Y = /y/gi.test(direction)
- ,self = this
- ;
- $(this).touchmove({
- touchmove:function(ex){
- X && $(this).scrollLeft($(this).scrollLeft() - ex.deltaX);
- Y && $(this).scrollTop($(this).scrollTop() - ex.deltaY);
- },
- touchend:function(e){
- var $self = $(this)
- ,timeDuration = 3000
- ,aa = 20
- ,speedX = e.speedX
- ,speedY = e.speedY
- ,source = e.tomSource
- ;
- //d(speedY);
- ///*
- (function show(time){
- if(!source.animation){return;}
- source.animation = window.setTimeout(function(){
- if(time > 90){ return; }
- X && $self.scrollLeft($self.scrollLeft() - ha(time,speedX) * aa );
- Y && $self.scrollTop($self.scrollTop() - ha(time,speedY) * aa );
- show(++time);
- },aa);
- })(1);
- function ha(x,maxSpeed){
- //return maxSpeed / x;//y = 100 / x;
- //return maxSpeed - maxSpeed / 100 * x;// y = -x + 100;
- return (1 - Math.sqrt(10000-(x-100)*(x-100)) / 100) * maxSpeed ;//y = -sqrt(10000-(x-100)2) + 100
- }
- }
- });
- return $(this);
- }
- $.fn.touchScrollX = function(){$(this).touchScroll("x");};
- $.fn.touchScrollY = function(){$(this).touchScroll("y");};
- })(jQuery);
IOS设备上网页中的页面滚动效果模拟的更多相关文章
- 【转】使IFRAME在iOS设备上支持滚动
原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚 很长时间以来, iOS设备上Safari中超出边界的元素将 ...
- 使IFRAME在iOS设备上支持滚动
原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚很长时间以来, iOS设备上Safari中超出边界的元素将不 ...
- 怎样将游戏从Unity导到iOS设备上
当我开始开发自己的iOS游戏时,我会考虑的第一件事便是如何将其导出到设备中,如此有效地测试我的游戏.最初,该过程看似很长且复杂,我所遇到的主要问题是,尽管存在许多资源,但是它们并非完全来自同样的地方, ...
- ScrollMe – 在网页中加入各种滚动动画效果
ScrollMe 是一款 jQuery 插件,用于给网页添加简单的滚动效果.当你向下滚动页面的时候,ScrollMe 可以缩放,旋转和平移页面上的元素.它易于设置,不需要任何自定义的 JavaScri ...
- 在Windows笔记本上调试运行在iOS设备上的前端应用
我在每天工作中需要在不同的移动设备上测试我们开发的前端应用是否正常工作,比如iOS设备和Android设备.我用的工作笔记本电脑又是Lenovo的,安装的是Windows操作系统. 有的时候一个开发好 ...
- 不通过App Store,在iOS设备上直接安装应用程序(转)
今天在iOS设备上安装天翼云存储app,在safari上直接打开http://cloud.189.cn/wap/index.jsp,点击“点击免费安装”,如下图: 神奇的事情发生了,设备上直接下载ap ...
- 不通过AppStore,在iOS设备上直接安装应用程序的原理
本文转载至 http://mobile.51cto.com/hot-439095.htm 通过itms-services协议,可以通过safari浏览器直接在iOS设备上安装应用程序.利用这种方式, ...
- ios真机使用fixed定位页面滚动时fixed定位的元素也会跟着滚动
到了ios真机APP中,页面向下滚动,fixed的元素也跟着滚,虽然最后它还是到了它该在的地方,但是它跟着滚动也很影响页面的流畅性和交互性好伐.
- jquery keyup 在IOS设备上输入中文时不触发
今天做一个异步查询功能的时候发现在IOS设备上查询中文时keyup没有触发,在其他设备上时可以的,后来在stackoverflow上找到下面这种解决方法,贴出来算是抛砖引玉了. $h_input.on ...
随机推荐
- mybatis---知识点复习
mybatis的配置文件是configuation.xml是配置文件,主要是配置jdbc(用来创建sessionfactory)以及映射文件的别名, 一对多: <mapper namespace ...
- openstack私有云布署实践【14.1 登录页dashboard-controller(科兴环境)】
2台kxcontroller安装组件 # yum install openstack-dashboard -y 修改一样的配置 vi /etc/openstack-dashboard/local_ ...
- Java线程的几种状态
一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运 ...
- Flood-it!
Flood-it! 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4127/http://acm.split.hdu.edu.cn/showproble ...
- PHP学习过程_Symfony_(1)
从今天开始学习php,感兴趣的同学欢迎一块讨论学习,QQ群新群182983780; 1:配置环境变量 把这php和php5http://pan.baidu.com/s/1pKDq9tT两个文件同时c盘 ...
- js--javascript中字符串常用操作总结、JS字符串操作大全
字符串的操作在js中非常频繁,也非常重要.以往看完书之后都能记得非常清楚,但稍微隔一段时间不用,便会忘得差不多,记性不好是硬伤啊...今天就对字符串的一些常用操作做个整理,一者加深印象,二者方便今后温 ...
- 《JS权威指南学习总结--第十一章子集和扩展》
js子集和扩展:http://www.cnblogs.com/ahthw/p/4298449.html ES6新增let和const关键字:http://www.cnblogs.com/telnetz ...
- Linux启动新进程的几种方法及比较[转]
有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些 ...
- c# propertyGrid下拉选项
实现下面效果的propertygrid属性下拉选择
- digitalocean网站打不开,大陆无法正常访问怎么办?
在中国大陆,由于某些恶心的原因,digitalocean官方网站经常出现无法打开,或者打开后网页异常的情况,如果你是一个新注册用户,你甚至会被吓到,一个全球知名的vps主机商网站可能是这样的: 我的天 ...