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 相关文章推荐
扩展String功能方法
Sep 22 Javascript
jquery ready(fn)事件使用介绍
Aug 21 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
JavaScript中继承用法实例分析
May 16 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
Feb 18 Javascript
Node.js+Express配置入门教程详解
May 19 Javascript
使用jQuery制作Web页面遮罩层插件的实例教程
May 26 Javascript
javascript事件冒泡简单示例
Jun 20 Javascript
vue实现多级菜单效果
Oct 19 Javascript
JS动态图片的实现方法完整示例
Jan 13 Javascript
Vue实现简单计算器案例
Feb 25 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
基于PHP导出Excel的小经验 完美解决乱码问题
2013/06/10 PHP
ThinkPHP控制器间实现相互调用的方法
2014/10/31 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
Javascript remove 自定义数组删除方法
2009/10/20 Javascript
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
jquery调用wcf并展示出数据的方法
2011/07/07 Javascript
js获取当前日期代码适用于网页头部
2013/06/27 Javascript
javascript的创建多行字符串的7种方法
2014/04/29 Javascript
jquery动态改变form属性提交表单
2014/06/03 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
2015/04/06 Javascript
jQuery中的siblings用法实例分析
2015/12/24 Javascript
基于javascript实现根据身份证号码识别性别和年龄
2016/01/22 Javascript
JS控制文本域只读或可写属性的方法
2016/06/24 Javascript
JS中检测数据类型的几种方式及优缺点小结
2016/12/12 Javascript
JS实现密码框的显示密码和隐藏密码功能示例
2016/12/26 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
webstorm添加vue.js支持的方法教程
2017/07/05 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
2017/11/15 Javascript
搭建Vue从Vue-cli到router路由护卫的实现
2019/11/14 Javascript
[11:44]Ti9 OG夺冠时刻
2019/08/25 DOTA
[01:09:16]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第一场 1月25日
2021/03/11 DOTA
Python实现3行代码解简单的一元一次方程
2014/08/18 Python
使用Python编写爬虫的基本模块及框架使用指南
2016/01/20 Python
Python中的日期时间处理详解
2016/11/17 Python
Python延时操作实现方法示例
2018/08/14 Python
CSS3中的content属性使用示例
2015/07/20 HTML / CSS
Vision Direct比利时:在线订购隐形眼镜
2019/08/27 全球购物
机电专业大学生求职信
2013/10/04 职场文书
市场营销专科应届生求职信
2013/11/24 职场文书
2015年乡镇科普工作总结
2015/05/13 职场文书
十月围城观后感
2015/06/08 职场文书
退休职工欢送会致辞
2015/08/01 职场文书
学习雷锋主题班会
2015/08/14 职场文书
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
springboot读取resources下文件的方式详解
2022/06/21 Java/Android