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 相关文章推荐
javascript 变量作用域 代码分析
Jun 26 Javascript
javascript 伪数组实现方法
Oct 11 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
May 12 Javascript
angularjs 处理多个异步请求方法汇总
Jan 06 Javascript
js判断浏览器版本以及浏览器内核的方法
Jan 20 Javascript
第一次接触神奇的Bootstrap基础排版
Jul 26 Javascript
codeMirror插件使用讲解
Jan 16 Javascript
Vue常用的几个指令附完整案例
Nov 06 Javascript
JavaScript文本特效实例小结【3个示例】
Dec 22 Javascript
vue2.0 如何在hash模式下实现微信分享
Jan 22 Javascript
js实现动态时钟
Mar 12 Javascript
使用jquery实现轮播图效果
Jan 02 jQuery
浅谈如何实现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翻页类
2009/06/01 PHP
PHP实现多进程并行操作的详解(可做守护进程)
2013/06/18 PHP
基于PHP后台的Android新闻浏览客户端
2016/05/23 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
php设计模式之抽象工厂模式分析【星际争霸游戏案例】
2020/01/23 PHP
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
JS实现随机化快速排序的实例代码
2013/08/01 Javascript
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
基于javascript实现动态时钟效果
2020/08/18 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
jQuery图片拖动组件Dropzone用法示例
2017/01/17 Javascript
原生js实现对Ajax的封装(仿jquery)
2017/01/22 Javascript
react-router browserHistory刷新页面404问题解决方法
2017/12/29 Javascript
动态内存分配导致影响Javascript性能的问题
2018/12/18 Javascript
详解用场景去理解函数柯里化(入门篇)
2019/04/11 Javascript
js如何验证密码强度
2020/03/18 Javascript
vue或react项目生产环境去掉console.log的操作
2020/09/02 Javascript
Windows下为Python安装Matplotlib模块
2015/11/06 Python
Python拼接字符串的7种方法总结
2018/11/01 Python
selenium+python自动化测试环境搭建步骤
2019/06/03 Python
Python3 Tkinkter + SQLite实现登录和注册界面
2019/11/19 Python
python实现拉普拉斯特征图降维示例
2019/11/25 Python
python二维键值数组生成转json的例子
2019/12/06 Python
Python中bisect的使用方法
2019/12/31 Python
python用pip install时安装失败的一系列问题及解决方法
2020/02/24 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
CSS3动画:5种预载动画效果实例
2017/04/05 HTML / CSS
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
财务管理专业毕业生求职信范文
2013/09/21 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
财产保全担保书
2015/01/20 职场文书
2019年英语版感谢信(8篇)
2019/09/29 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
redis cluster支持pipeline的实现思路
2021/06/23 Redis