JS+HTML5手机开发之滚动和惯性缓动实现方法分析


Posted in Javascript onJune 12, 2016

本文实例讲述了JS+HTML5手机开发之滚动和惯性缓动实现方法。分享给大家供大家参考,具体如下:

1. 滚动 以下是三种实现方式:

1) 利用原生的css属性 overflow: scroll div id= parent style = overflow:scroll; divid='content'内容区域/div /div Notice: 在android 有bug, 滚动完后会回退到最顶端的内容区域,解决办法是使用后两种方式实现

2)js 编程实现 思路:对比手指在屏幕上移动前后位置变化改变内容元素content

1. 滚动

以下是三种实现方式:

1) 利用原生的css属性 overflow: scroll

<div id="parent" style="overflow:scroll;>
  <div id='content'>内容区域</div>
</div>

Notice:

在android 有bug, 滚动完后会回退到最顶端的内容区域,解决办法是使用后两种方式实现

2)js 编程实现

思路:对比手指在屏幕上移动前后位置变化改变内容元素content的位置

第一步:设置parent的 overflow为hidden, 设置content的position为relative, top为0;

第二步:监听touch事件

var parent = document.getElementById('parent');
parent.addEventListener('touchstart', function(e) {
  // do touchstart
});
parent.addEventListener('touchmove', function(e) {
  // do touchmove
});
parent.addEventListener('touchend', function(e) {
  // do touchend
});

第三步:实现滚动代码

/**
 * 这里只实现垂直滚动
 */
var parent = document.getElementById('parent');
var content = document.getElementById('content')
var startY = 0; // 初始位置
var lastY = 0; // 上一次位置
parent.addEventListener('touchstart', function(e) {
  lastY = startY = e.touches[0].pageY;
});
parent.addEventListener('touchmove', function(e) {
  var nowY = e.touches[0].pageY;
  var moveY = nowY - lastY;
  var contentTop = content.style.top.replace('px', '');
  // 设置top值移动content
  content.style.top = (parseInt(contentTop) + moveY) + 'px';
  lastY = nowY;
});
parent.addEventListener('touchend', function(e) {
  // do touchend
  var nowY = e.touches[0].pageY;
  var moveY = nowY - lastY;
  var contentTop = content.style.top.replace('px', '');
  // 设置top值移动content
  content.style.top = (parseInt(contentTop) + moveY) + 'px';
  lastY = nowY;
});

第四步:优化

上边代码在手机上运行效果相对PC上要卡很多

优化部分请参见:

3) 使用iScroll4框架

var scroll = new iScroll('parent', {
hScrollbar: false,
vScrollbar: true,
checkDOMChanges : true
});

框架官网:http://cubiq.org/iscroll-4

2.惯性缓动

思路:取手指最后一段时间在屏幕上划动的平均速度v,让v按一个递减函数变化,直到不能移动或v<=0

/**
 * 这里只实现垂直滚动
 */
var parent = document.getElementById('parent');
var content = document.getElementById('content')
var startY = 0; // 初始位置
var lastY = 0; // 上一次位置
/**
 * 用于缓动的变量
 */
var lastMoveTime = 0;
var lastMoveStart = 0;
var stopInertiaMove = false; // 是否停止缓动
parent.addEventListener('touchstart', function(e) {
  lastY = startY = e.touches[0].pageY;
  /**
   * 缓动代码
   */
  lastMoveStart = lastY;
  lastMoveTime = e.timeStamp || Date.now();
  stopInertiaMove = true;
});
parent.addEventListener('touchmove', function(e) {
  var nowY = e.touches[0].pageY;
  var moveY = nowY - lastY;
  var contentTop = content.style.top.replace('px', '');
  // 设置top值移动content
  content.style.top = (parseInt(contentTop) + moveY) + 'px';
  lastY = nowY;
  /**
   * 缓动代码
   */
  var nowTime = e.timeStamp || Date.now();
  stopInertiaMove = true;
  if(nowTime - lastMoveTime > 300) {
    lastMoveTime = nowTime;
    lastMoveStart = nowY;
  }
});
parent.addEventListener('touchend', function(e) {
  // do touchend
  var nowY = e.touches[0].pageY;
  var moveY = nowY - lastY;
  var contentTop = content.style.top.replace('px', '');
  var contentY = (parseInt(contentTop) + moveY);
  // 设置top值移动content
  content.style.top = contentY + 'px';
  lastY = nowY;
  /**
   * 缓动代码
   */
  var nowTime = e.timeStamp || Date.now();
  var v = (nowY - lastMoveStart) / (nowTime - lastMoveTime); //最后一段时间手指划动速度
  stopInertiaMove = false;
  (function(v, startTime, contentY) {
    var dir = v > 0 ? -1 : 1; //加速度方向
    var deceleration = dir*0.0006;
    var duration = v / deceleration; // 速度消减至0所需时间
    var dist = v * duration / 2; //最终移动多少
    function inertiaMove() {
      if(stopInertiaMove) return;
      var nowTime = e.timeStamp || Date.now();
      var t = nowTime-startTime;
      var nowV = v + t*deceleration;
      // 速度方向变化表示速度达到0了
      if(dir*nowV < 0) {
        return;
      }
      var moveY = (v + nowV)/2 * t;
      content.style.top = (contentY + moveY) + "px";
      setTimeout(inertiaMove, 10);
    }
    inertiaMove();
  })(v, nowTime, contentY);
});

PS:这里再为大家推荐几款代码格式化、美化工具,相信大家在以后的开发过程中会用得到:

在线JavaScript代码美化、格式化工具:
http://tools.3water.com/code/js

JavaScript压缩/格式化/加密工具:
http://tools.3water.com/code/jscompress

json代码在线格式化/美化/压缩/编辑/转换工具:
http://tools.3water.com/code/jsoncodeformat

在线JSON代码检验、检验、美化、格式化工具:
http://tools.3water.com/code/json

希望本文所述对大家jQuery程序设计有所帮助。

Javascript 相关文章推荐
用tip解决Ext列宽度不够的问题
Dec 13 Javascript
js 分栏效果实现代码
Aug 29 Javascript
confirm的用法示例用于按钮操作时确定是否执行
Jun 19 Javascript
jquery 实现两Select 标签项互调示例代码
Sep 25 Javascript
原生JS实现平滑回到顶部组件
Mar 16 Javascript
Angularjs中UI Router的使用方法
May 14 Javascript
微信小程序 数据封装,参数传值等经验分享
Jan 09 Javascript
bootstrap侧边栏圆点导航
Jan 11 Javascript
JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)
Jun 19 Javascript
Vuejs中使用markdown服务器端渲染的示例
Nov 22 Javascript
Vue三层嵌套路由的示例代码
May 05 Javascript
JavaScript Image对象实现原理实例解析
Aug 26 Javascript
浅谈如何实现easyui的datebox格式化
Jun 12 #Javascript
JQuery的attr 与 val区别
Jun 12 #Javascript
从重置input file标签中看jQuery的 .val() 和 .attr(“value”) 区别
Jun 12 #Javascript
Java框架SSH结合Easyui控件实现省市县三级联动示例解析
Jun 12 #Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
Jun 12 #Javascript
javascript jquery对form元素的常见操作详解
Jun 12 #Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
Jun 12 #Javascript
You might like
如何将数据从文本导入到mysql
2006/10/09 PHP
利用PHP动态生成VRML网页
2006/10/09 PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
2017/02/28 PHP
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
javascript ajax的5种状态介绍
2014/08/18 Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
2015/03/04 Javascript
javascript实现淘宝幻灯片广告展示效果
2015/04/27 Javascript
jQuery手机拨号界面特效代码分享
2015/08/27 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
2017/09/14 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
通过vue-cli来学习修改Webpack多环境配置和发布问题
2017/12/22 Javascript
vue 路由页面之间实现用手指进行滑动的方法
2018/02/23 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
2018/03/08 Javascript
详解js模板引擎art template数组渲染的方法
2018/10/09 Javascript
浅谈Node框架接入ELK实践总结
2019/02/22 Javascript
VUE 动态组件的应用案例分析
2019/12/02 Javascript
javascript事件循环event loop的简单模型解释与应用分析
2020/03/14 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
[02:51]2014DOTA2国际邀请赛 IG战队官方纪录片
2014/07/21 DOTA
将图片文件嵌入到wxpython代码中的实现方法
2014/08/11 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
Python3之外部文件调用Django程序操作model等文件实现方式
2020/04/07 Python
Python中logger日志模块详解
2020/08/04 Python
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
英国最受信任的在线眼镜商之一:Fashion Eyewear
2019/10/31 全球购物
银行职员个人的工作自我评价
2014/02/15 职场文书
师德师风承诺书
2014/05/23 职场文书
施工安全协议书范本
2014/09/26 职场文书
村党支部书记个人对照材料汇报
2014/10/26 职场文书
2015年环境整治工作总结
2015/05/22 职场文书
在redisCluster中模糊获取key方式
2021/07/09 Redis
frg-100简单操作(设置)说明
2022/04/05 无线电
Java实现带图形界面的聊天程序
2022/06/10 Java/Android