HTML5手机开发学习:实现滚动和惯性缓动效果

本文转载于:猿2048网站⇨HTML5手机开发学习:实现滚动和惯性缓动效果

 滚动
 
以下是三种实现方式:
 
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事件
 

1
2
3
4
5
6
7
8
9
10
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
  });
 
第三步:实现滚动代码
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
   * 这里只实现垂直滚动
   */
  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上要卡很多
 
) 使用iScroll4框架
 
  var scroll = new iScroll('parent', {
  hScrollbar: false,
  vScrollbar: true,
  checkDOMChanges : true
 
  });
 
框架官网: http://cubiq.org/iscroll-4
 
惯性缓动
 
思路:取手指最后一段时间在屏幕上划动的平均速度v,让v按一个递减函数变化,直到不能移动或v<=0
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
   * 这里只实现垂直滚动
   */
  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);
  }); 

更多专业前端知识,请上 【猿2048】www.mk2048.com

猜你喜欢

转载自www.cnblogs.com/qianduanwriter/p/11742198.html
今日推荐