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 相关文章推荐
js实现单行文本向上滚动效果实例代码
Nov 28 Javascript
javascript面向对象之对象的深入理解
Jan 13 Javascript
Javascript基础教程之变量
Jan 18 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
Jun 03 Javascript
jQuery源码分析之sizzle选择器详解
Feb 13 Javascript
js实现显示手机号码效果
Mar 09 Javascript
详解node.js搭建代理服务器请求数据
Apr 08 Javascript
深入研究jQuery图片懒加载 lazyload.js使用方法
Aug 16 jQuery
vue 微信授权登录解决方案
Apr 10 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
Sep 28 Javascript
Nuxt.js实战和配置详解
Aug 05 Javascript
JS制作简易计算器的实例代码
Jul 04 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
模拟SQLSERVER的两个函数:dateadd(),datediff()
2006/10/09 PHP
用PHP的超级变量$_GET获取HTML表单(Form) 数据
2011/05/07 PHP
基于PHP生成静态页的实现方法
2013/05/10 PHP
Thinkphp关闭缓存的方法
2015/06/26 PHP
Zend Framework生成验证码并实现验证码验证功能(附demo源码下载)
2016/03/22 PHP
深入理解PHP之OpCode原理详解
2016/06/01 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
浏览器解析js生成的html出现样式问题的解决方法
2012/04/16 Javascript
js实现的map方法示例代码
2014/01/13 Javascript
jQuery.ajax 跨域请求webapi设置headers的解决方案
2016/08/08 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
bootstrap表单按回车会自动刷新页面的解决办法
2017/03/08 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
three.js中文文档学习之创建场景
2017/11/20 Javascript
node.js部署之启动后台运行forever的方法
2018/05/23 Javascript
[00:59]PWL开团时刻DAY7——我在赶
2020/11/06 DOTA
Python自动登录126邮箱的方法
2015/07/10 Python
详解python中字典的循环遍历的两种方式
2017/02/07 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
配置python的编程环境之Anaconda + VSCode的教程
2020/03/29 Python
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
Html5实现如何在两个div元素之间拖放图像
2013/03/29 HTML / CSS
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
应聘护士自荐信
2013/10/21 职场文书
会计专业应届生自荐信
2014/02/07 职场文书
店面销售职位的职责
2014/03/09 职场文书
单位委托书范本
2014/04/04 职场文书
人资专员岗位职责
2014/04/04 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
课外活动总结范文
2014/07/09 职场文书
学习党代会心得体会
2014/09/05 职场文书
IDEA2021.2配置docker如何将springboot项目打成镜像一键发布部署
2021/09/25 Java/Android
Windows Server 2008 修改远程登录端口以及配置防火墙
2022/04/28 Servers