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打造TabPanel效果代码
May 22 Javascript
js中根据字数截取字符串,不能截断url
Jan 12 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
js脚本获取webform服务器控件的方法
May 16 Javascript
5个书写JavaScript代码的坏习惯,看看你中枪了没?
Nov 06 Javascript
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
Aug 11 Javascript
AngularJS控制器controller正确的通信的方法
Jan 25 Javascript
微信小程序 框架详解及实例应用
Sep 26 Javascript
jquery滚动条插件(可以自定义)
Dec 11 Javascript
jQuery实现文章图片弹出放大效果
Apr 06 jQuery
JS中的算法与数据结构之集合(Set)实例详解
Aug 20 Javascript
原生js+canvas实现贪吃蛇效果
Aug 02 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使用session二维数组实例
2014/11/06 PHP
PHP递归创建多级目录
2015/11/05 PHP
laravel框架创建授权策略实例分析
2019/11/22 PHP
javascript网页关键字高亮代码
2008/07/30 Javascript
JavaScript高级程序设计 错误处理与调试学习笔记
2011/09/10 Javascript
js导出txt示例代码
2014/01/14 Javascript
JQuery中extend使用介绍
2014/03/13 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
2014/04/15 Javascript
详解js图片轮播效果实现原理
2015/12/17 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
总结javascript中的六种迭代器
2016/08/16 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
jQuery弹出层插件popShow(改进版)用法示例
2017/01/23 Javascript
vue-router跳转页面的方法
2017/02/09 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
2018/09/12 Javascript
支付宝小程序自定义弹窗dialog插件的实现代码
2018/11/30 Javascript
深入浅析Vue 中 ref 的使用
2019/04/29 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
2019/05/28 jQuery
基于js实现复制内容到操作系统粘贴板过程解析
2019/10/11 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
[03:13]DOTA2-DPC中国联赛1月25日Recap集锦
2021/03/11 DOTA
Python httplib模块使用实例
2015/04/11 Python
Fiddler如何抓取手机APP数据包
2016/01/22 Python
Python编码爬坑指南(必看)
2016/06/10 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
Python实现字典(dict)的迭代操作示例
2018/06/05 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
pycharm显示远程图片的实现
2019/11/04 Python
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
实习自荐信
2013/10/13 职场文书
继承公证书
2014/04/09 职场文书
我爱我的祖国演讲稿
2014/05/04 职场文书
优秀语文教师事迹
2014/05/18 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
新员工入职感言范文!
2019/07/04 职场文书
一条慢SQL语句引发的改造之路
2022/03/16 MySQL