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
- });
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);
- });
转自:http://blog.csdn.net/zzm_justin/article/details/8476373