可能咋一看不知道我说的是个啥,因为iOS本来就用这功能的啊,还模拟它干啥?先听我说下项目背景哈

我现在开发的是一个webapp,主要是用在ipad上,这个app的大小是固定大小的,为了防止触摸它出现弹性滚动,我加个句代码:

  1. $(document).bind('touchmove', function(e) {
  2. e.preventDefault();
  3. });

这样这个页面就被我锁死了,不会出现讨厌的弹性滚动了,再加上一些meta属性(我的blog里有这些)全屏啥的,基本上跟nativeapp无异了。

但是呢,问题出来了,里面有个div里面内容比较多,需要用到滚动条,现在的问题是,我的网页里设置这个div的overflow为scroll后,触摸这个div不能滚动了!我先试着把上面的代码注释点,发现可以滚动了,但是效果很差,没有ios自带的那种手离开后还会滚动一会的那种“刹车”的效果,于是呢,就想着自己搞一个出来,于是就写了一个jQuery插件,实现了上下左右滑动和轻拍(因为点击事件在ipad上有半秒延迟),下面会有下载地址。关于滚动效果呢,是我花了一整天时间研究出来的,觉得收获很大,所以拿出来跟大家分享下,以下是一些核心代码:

  1. (function show(time){
  2. if(!source.animation){return;}
  3. source.animation = window.setTimeout(function(){
  4. if(time > 90){ return; }
  5. X && $self.scrollLeft($self.scrollLeft() - ha(time,speedX) * aa );
  6. Y && $self.scrollTop($self.scrollTop() - ha(time,speedY) * aa );
  7. show(++time);
  8. },aa);
  9. })(1);

函数ha:

  1. function ha(x,maxSpeed){
  2. //return maxSpeed / x;//y = 100 / x;
  3. //return maxSpeed - maxSpeed / 100 * x;// y = -x + 100;
  4. return (1 - Math.sqrt(10000-(x-100)*(x-100)) / 100) * maxSpeed ;//y = -sqrt(10000-(x-100)2) + 100
  5. }

上面第一段代码的意思是在手指离开屏幕之后要执行的一个连续动画,可以看到,随着时间速度越来越慢,速度的变化由函数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

    1. (function($){
    2. //if (!document.documentElement.ontouchstart){return;}
    3. var events = "touchmove,tap,swiperight,swipeleft,swipeup,swipedown";
    4. var proto = function($e,type,fn){
    5. this.$e = $e;
    6. this.type = type;
    7. this.fn = fn;
    8. };
    9. proto.prototype = {
    10. swipeDistance:40,
    11. startX:0,
    12. startY:0,
    13. tempX:0,
    14. tempY:0,
    15. startTime:undefined,
    16. animation:undefined,
    17. touchmove:function(e){
    18. var self = e.data;
    19. e = e.originalEvent;
    20. if (e.targetTouches.length >= 1) {
    21. var touch = e.targetTouches[0];
    22. if(self._touchmove){
    23. self.fn.touchmove.call(this,{
    24. deltaX:touch.pageX - self.tempX,
    25. deltaY:touch.pageY - self.tempY,
    26. x:touch.pageX,
    27. y:touch.pageY,
    28. tomSource:self
    29. });
    30. }
    31. self.tempX = touch.pageX;
    32. self.tempY = touch.pageY;
    33. }
    34. },
    35. touchstart:function(e){
    36. var self = e.data;
    37. e = e.originalEvent;
    38. if (e.targetTouches.length >= 1) {
    39. var touch = e.targetTouches[0];
    40. self.tempX = self.startX = touch.pageX;
    41. self.tempY = self.startY = touch.pageY;
    42. self.animation = undefined;
    43. self.startTime = +new Date;
    44. self.fn.touchstart &&
    45. self.fn.touchstart.call(this,{x:e.pageX,y:e.pageY,tomSource:self});
    46. }
    47. },
    48. touchend:function(e){
    49. var self = e.data;
    50. e = e.originalEvent;
    51. if (e.changedTouches.length >= 1) {
    52. self.animation = true;
    53. var touch = e.changedTouches[0]
    54. ,now = +new Date()
    55. ,dX = touch.pageX - self.startX
    56. ,dY = touch.pageY - self.startY
    57. ,AdX = Math.abs(dX)
    58. ,AdY = Math.abs(dY)
    59. ,timeD = now - self.startTime;
    60. if(
    61. (timeD < 100 && AdX < 15 && AdY < 15 && self._tap) ||
    62. (dX > self.swipeDistance && AdX > AdY && self._swiperight) ||
    63. (-dX > self.swipeDistance && AdX > AdY && self._swipeleft) ||
    64. (dY > self.swipeDistance && AdY > AdX && self._swipedown)  ||
    65. (-dY > self.swipeDistance && AdY > AdX && self._swipeup)){
    66. self.fn.call(this,{});
    67. }
    68. var speedX = dX / timeD;
    69. var speedY = dY / timeD;
    70. //d(self.startY + "," + touch.pageY);
    71. self.fn.touchend &&
    72. self.fn.touchend.call(this,{
    73. x:touch.pageX,
    74. y:touch.pageY,
    75. speedX:speedX,
    76. speedY:speedY,
    77. tomSource:self
    78. });
    79. }
    80. },
    81. handle:function(){
    82. var self = this;
    83. $.each(events.split(',')
    84. ,function(i,item){
    85. if(item == self.type){
    86. self[ "_" + item ] = true;
    87. }
    88. });
    89. self.$e.bind("touchmove",self,self.touchmove);
    90. self.$e.bind("touchstart",self,self.touchstart);
    91. self.$e.bind("touchend",self,self.touchend);
    92. }
    93. };
    94. $.each(events.split(","),function(i,name){
    95. $.fn[name] = function(fn){
    96. var touches = new proto($(this),name,fn);
    97. touches.handle();
    98. return $(this);
    99. }
    100. });
    101. $.fn.touchScroll = function(direction){
    102. var X = /x/gi.test(direction)
    103. ,Y = /y/gi.test(direction)
    104. ,self = this
    105. ;
    106. $(this).touchmove({
    107. touchmove:function(ex){
    108. X && $(this).scrollLeft($(this).scrollLeft() - ex.deltaX);
    109. Y && $(this).scrollTop($(this).scrollTop() - ex.deltaY);
    110. },
    111. touchend:function(e){
    112. var $self = $(this)
    113. ,timeDuration = 3000
    114. ,aa = 20
    115. ,speedX = e.speedX
    116. ,speedY = e.speedY
    117. ,source = e.tomSource
    118. ;
    119. //d(speedY);
    120. ///*
    121. (function show(time){
    122. if(!source.animation){return;}
    123. source.animation = window.setTimeout(function(){
    124. if(time > 90){ return; }
    125. X && $self.scrollLeft($self.scrollLeft() - ha(time,speedX) * aa );
    126. Y && $self.scrollTop($self.scrollTop() - ha(time,speedY) * aa );
    127. show(++time);
    128. },aa);
    129. })(1);
    130. function ha(x,maxSpeed){
    131. //return maxSpeed / x;//y = 100 / x;
    132. //return maxSpeed - maxSpeed / 100 * x;// y = -x + 100;
    133. return (1 - Math.sqrt(10000-(x-100)*(x-100)) / 100) * maxSpeed ;//y = -sqrt(10000-(x-100)2) + 100
    134. }
    135. }
    136. });
    137. return $(this);
    138. }
    139. $.fn.touchScrollX = function(){$(this).touchScroll("x");};
    140. $.fn.touchScrollY = function(){$(this).touchScroll("y");};
    141. })(jQuery);

IOS设备上网页中的页面滚动效果模拟的更多相关文章

  1. 【转】使IFRAME在iOS设备上支持滚动

    原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚 很长时间以来, iOS设备上Safari中超出边界的元素将 ...

  2. 使IFRAME在iOS设备上支持滚动

    原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚很长时间以来, iOS设备上Safari中超出边界的元素将不 ...

  3. 怎样将游戏从Unity导到iOS设备上

    当我开始开发自己的iOS游戏时,我会考虑的第一件事便是如何将其导出到设备中,如此有效地测试我的游戏.最初,该过程看似很长且复杂,我所遇到的主要问题是,尽管存在许多资源,但是它们并非完全来自同样的地方, ...

  4. ScrollMe – 在网页中加入各种滚动动画效果

    ScrollMe 是一款 jQuery 插件,用于给网页添加简单的滚动效果.当你向下滚动页面的时候,ScrollMe 可以缩放,旋转和平移页面上的元素.它易于设置,不需要任何自定义的 JavaScri ...

  5. 在Windows笔记本上调试运行在iOS设备上的前端应用

    我在每天工作中需要在不同的移动设备上测试我们开发的前端应用是否正常工作,比如iOS设备和Android设备.我用的工作笔记本电脑又是Lenovo的,安装的是Windows操作系统. 有的时候一个开发好 ...

  6. 不通过App Store,在iOS设备上直接安装应用程序(转)

    今天在iOS设备上安装天翼云存储app,在safari上直接打开http://cloud.189.cn/wap/index.jsp,点击“点击免费安装”,如下图: 神奇的事情发生了,设备上直接下载ap ...

  7. 不通过AppStore,在iOS设备上直接安装应用程序的原理

    本文转载至  http://mobile.51cto.com/hot-439095.htm 通过itms-services协议,可以通过safari浏览器直接在iOS设备上安装应用程序.利用这种方式, ...

  8. ios真机使用fixed定位页面滚动时fixed定位的元素也会跟着滚动

    到了ios真机APP中,页面向下滚动,fixed的元素也跟着滚,虽然最后它还是到了它该在的地方,但是它跟着滚动也很影响页面的流畅性和交互性好伐.

  9. jquery keyup 在IOS设备上输入中文时不触发

    今天做一个异步查询功能的时候发现在IOS设备上查询中文时keyup没有触发,在其他设备上时可以的,后来在stackoverflow上找到下面这种解决方法,贴出来算是抛砖引玉了. $h_input.on ...

随机推荐

  1. 8VC Venture Cup 2017 - Elimination Round

    传送门:http://codeforces.com/contest/755 A题题意是给你一个数字n,让你找到一个数字m,使得n*m+1为合数,范围比较小,直接线性筛出1e6的质数,然后暴力枚举一下就 ...

  2. 淘淘商城_day05_课堂笔记

    今日大纲 学习Redis 使用Redis完成项目中缓存需求 实现商品详情页功能 缓存的需求 大广告位数据无需每次查询后台系统的接口,可以在前台系统添加缓存,提高访问首页的速度. 商品类目的数据也可以缓 ...

  3. 大数据时代之hadoop(一):hadoop安装

    1.hadoop版本介绍 0.20.2版本以前(不含该版本)的配置文件都在default.xml中. 0.20.x以后的版本不含有eclipse插件的jar包,由于eclipse的版本不一,所以就需要 ...

  4. 在ashx处理程序中,如果返回json串数据?

    可以通过一下代码: using System.Collections.Generic;using System.Web.Script.Serialization; SortedDictionary&l ...

  5. 2016WHD.china世界云计算日·北京站即将召开

    WHD.china自进驻中国以来,已在上海.北京成功举办多届,2015年于北京举办的会议更是盛况空前,注册参会者逾800人次,汇聚了国内外众多知名云服务商.IDC商.电子商务企业.电信运营商.ISP等 ...

  6. 轻量级的移动框架--zepto.js

    Zepto是一个轻量级的支持移动WebKit浏览器javascript移动端框架,框架支持jQuery语法,该框架的压缩包zepto.min.js 大小只有21K, 使用服务器端 gzip 压缩后大小 ...

  7. Ajax中参数带有html格式的 传入后台保存【一】

    因业务需求  要讲如下编辑器中带有样式的数据传入数据库保存 第一种方法  json格式传入 $(".privilegezn_page .btn_ok").click(functio ...

  8. deepin2014.1安装搜狗后却找不到图标及配置

    点开Input Method Configration; 点左下角添加输入法; 将Only  Ohow Current Language前 的勾去掉,选择出现的搜狗输入法. FYI.

  9. Java 序列化 transient关键字

    Java 序列化 transient关键字 @author 敏敏Alexia 转自:http://www.cnblogs.com/lanxuezaipiao/p/3369962.html 1. tra ...

  10. NSDictionary 的内部实现

    NSDictionary是IOS中使用的一种key-value容器,参考cocotron的源代码,NSDictionary使用NSMapTable实现. NSMapTable同样是一个key-valu ...