美文网首页web 杂谈WEB前端程序开发Web 前端开发
js 如何实现惯性滚动(简单实现)

js 如何实现惯性滚动(简单实现)

作者: 高少辉_骚辉 | 来源:发表于2017-07-25 11:57 被阅读369次

为什么需要惯性滚动

这个其实很好理解,因为如果没有惯性滚动的话,你在使用手机的时候,向上滑动会手拿起来,页面也就停下来了,这会用户体验很差,让用户感到很没有控制感。

惯性滚动是什么?

惯性滚动,是苹果早期发明的一个专利,主要是让用户在滑动手机终端的页面之后,不会马上挺下来,而是会像你推一辆小车那样有惯性的进行滑动,最后因为摩擦力而停止下来
惯性滚动,主要强调惯性这两个字

惯性是什么?
惯性是物体保持原来运动状态的一种属性(保持原来速度)
但是如果只有惯性,是停不下来的,所以还得有一个东西:摩擦力(提供了加速度)

如何实现?

回顾惯性的物理公式

  • f = ma
  • speed = initSpeed - a * ( t -T ) // 其中 T 为开始时候的时间

改编公式

speed = speed - a // speed 为上一时刻的速度,减去 a 等于这一时刻,这可以使得不用关心时间 t

而在现实生活中,摩擦力与速度成某种比例关系,我们设为函数 f

所以,f = f( speed ) 推理出加速度 a 和 speed 的关系 a = f( speed ) / m

我们把 a 和 speed 的函数关系,用 g() 表示,则有:a = f( speed ) / m = g( speed )

设 g() 满足以下关系,则有:

  • a = A ; (speed / m) > A
  • a = (speed / m) ; (speed / m) > A

Ps: 为什么药使用分段函数?因为现实中摩擦力虽然和速度有关系,但是是有上限的,不然你一下就停下来了,还是让人不爽

到现在为止,我们已经找到了加速度和速度的关系了,下一步我要做的就是把这些公式套用到我们的代码当中

代码实现逻辑

首先我们分析公式后发现,我们需要的根据用户的滑动获取到滑动的速度,那怎么计算这个速度呢?
我们知道在移动 web 开发中,用户操作屏幕时候拥有很多事件,并且每一个事件,我们都可以获取到用户点击屏幕的位置信息,而如果我们可以获取到用户触摸下屏幕时候的位置是时间和用户手离开屏幕时候的位置和时间,就可以计算出滑动的速度( 路程 / ( 离开时的时间 - 触摸时的时间 ) )
速度有了,我们现在应该去滑动什么呢?我们先来给页面进行布局

<style>
.s-body {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    margin: 0 auto;
}
.s-content {
    width: 100%;
    height: 1000px;
    -webkit-user-select: none;
    position: absolute;
    top: 0;
    left: 0;
}
</style>
<div class="s-body">
    <div class="s-content">
     这边是真正的内容区
    </div>
</div>

根据上面的布局,我们就可以很清晰的知道,滑动的时候我们滑动的是 .s-content ,但是还有一个问题就是,当用户在滑动过程中,页面是需要跟着手指一起动的,不然就会很怪,所以还需要使用到,页面手机在屏幕移动上面的事件,并根据移动的位置,移动页面

var content = document.querySelector('.s-content')
,   body = document.querySelector('.s-body')
body.ontouchstart = function (event) {  // 手触摸下去那一刻
   // 需要存几个东西
   // 起点的位置、这时的时间、.s-content 的起点位置

   body.ontouchmove = function (event) {  // 手在屏幕上移动
      // 需要计算 .s-content 的当前位置,并赋值,计算公式是:
      // 获取到手当前的位置 - 起点的位置 + .s-content 的起点位置
   }
   body.ontouchend = function (event) {  // 手离开屏幕
      // 计算初始 speed 
      //  speed = ( 结束时候手的位置 - 起点的位置 )  / ( 结束时候的时间 - 开始时的时间 )
      // 打开定时器,根据 speed 让 .s-content 进行运动,然后 speed 进行减速运动 speed = speed - a ; a = g( speed ) ; 根据这两个公式进行运算即可
   }
}

到这里,就基本把写一个滚动条的基本流程介绍完了,这个教程只是基本的简介教程,代码编写方式不优雅,主要用于提供思路。其实市面上也有很多惯性滚动的插件,但是有些滑动的时候让人不能特别愉快,有两个原因

  • 摩擦力值没有设置好(也就是加速度没有弄好)导致过快或者过慢停下来了
  • 还有就是,真正好的用户体验应使用手指离开屏幕时候的瞬时速度,而不是使用平均速度,本教程为了容易理解采用了平均速度(才用平均速度的时候,需要给 300ms 的限制,如果手在屏幕上停留了 大于 300ms 就不进行惯性滚动,如果不加这个会导致,你很快滑动屏幕,然后手停下来一会儿后,用户的心里预期是不会动,但是它竟然滑动了,可以去把我的源码拷贝下来 把里面的 第 83 行注释掉,放你手机上体验一下)

到这里就结束了哦,谢谢
源码链接

演示链接
ps: 请用手机扫码打开。只支持 ios 系统,没有进行兼容性处理

相关文章

网友评论

  • HT88888:您好, ios 系统也不支持滚动。

本文标题:js 如何实现惯性滚动(简单实现)

本文链接:https://www.haomeiwen.com/subject/awkwkxtx.html