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 相关文章推荐
JQuery选择器特辑 详细小结
May 14 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 Javascript
open 动态修改img的onclick事件示例代码
Nov 13 Javascript
js setTimeout()函数介绍及应用以倒计时为例
Dec 12 Javascript
js 实现浏览历史记录示例
Apr 20 Javascript
JS实现OCX控件的事件响应示例
Sep 17 Javascript
浅谈javascript中的instanceof和typeof
Feb 27 Javascript
浅谈利用JavaScript进行的DDoS攻击原理与防御
Jun 04 Javascript
微信小程序之多文件下载的简单封装示例
Jan 29 Javascript
vue router 源码概览案例分析
Oct 09 Javascript
vue-cli V3.0版本的使用详解
Oct 24 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
May 11 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 开发环境配置(Zend Server安装)
2010/04/28 PHP
将酷狗krc歌词解析并转换为lrc歌词php源码
2014/06/20 PHP
PHP使用Mysql事务实例解析
2014/09/08 PHP
php获取文件名后缀常用方法小结
2015/02/24 PHP
Yii2.0 模态弹出框+ajax提交表单
2016/05/22 PHP
jquery+thinkphp实现跨域抓取数据的方法
2016/10/15 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
Javascript改变CSS样式(局部和全局)
2013/12/18 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
jQuery中:has选择器用法实例
2014/12/30 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
jquery获取下拉框中的循环值
2017/02/08 Javascript
利用Node.js编写跨平台的spawn语句详解
2017/02/12 Javascript
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
uniapp微信小程序实现一个页面多个倒计时
2020/11/01 Javascript
[00:31]2016完美“圣”典风云人物:国士无双宣传片
2016/12/04 DOTA
[00:14]护身甲盾
2019/03/06 DOTA
Python黑帽编程 3.4 跨越VLAN详解
2016/09/28 Python
运动检测ViBe算法python实现代码
2018/01/09 Python
python输入中文的实例方法
2020/09/14 Python
Python基于staticmethod装饰器标示静态方法
2020/10/17 Python
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
Hotels.com越南:酒店预订
2019/10/29 全球购物
在C语言中实现抽象数据类型什么方法最好
2014/06/26 面试题
装修致歉信
2014/01/15 职场文书
应聘护理专业毕业自荐书范文
2014/02/12 职场文书
房屋出租协议书
2014/04/10 职场文书
共产党员岗位承诺书
2014/05/29 职场文书
婚前协议书范本两则
2014/10/16 职场文书
2014年护士长工作总结
2014/11/11 职场文书
倡议书格式及范文
2015/04/29 职场文书
2015年社区国庆节活动总结
2015/07/30 职场文书
聘任通知书
2015/09/21 职场文书
python中 Flask Web 表单的使用方法
2022/05/20 Python