JS与HTML5移动端滚动及惯性缓动实现详解

作者:纸飞机

时间:2026-10-30

浏览:205

本文详细解析了HTML5手机开发中滚动与惯性缓动的三种实现方式。首先介绍CSS overflow属性的局限性及Android端的兼容问题,随后深入讲解基于touch事件的JS原生滚动实现逻辑,包括位置监听与DOM操作。针对性能优化,推荐使用iScroll4框架。最后阐述惯性缓动原理,即通过计算手指滑动平均速度并应用递减函数实现自然停止效果,附带相关代码工具推荐。

文章目录

本文详细介绍在JavaScript与HTML5环境下,移动端页面滚动及惯性缓动功能的具体实现方案,供开发者参考借鉴。

移动端滚动实现的三种方式

主要涵盖以下三种滚动实现路径:

第一种方法是利用CSS原生属性 overflow: scroll。示例代码如下:div id="parent" style="overflow:scroll;" div id="content"内容区域/div/div。需要注意的是,该方法在Android系统存在已知Bug,即滚动结束后页面会自动回退至内容区域的最顶端。因此,建议采用后续介绍的两种替代方案来解决此问题。

第二种方法是通过JavaScript编程实现。核心思路在于监听并对比手指在屏幕上的移动前后位置变化,进而动态调整内容元素content的位置。

具体实现步骤如下:

具体实现步骤如下:

第一种方法是利用CSS原生属性 overflow: scroll


<div id="parent" style="overflow:scroll;>
  <div id='content'>内容区域</div>
</div>

注意事项:

Android系统存在Bug,滚动结束后页面会自动回退至内容区域的最顶端。建议使用后两种方案规避此问题。

第二种方法是通过JavaScript编程实现

核心思路:监听并对比手指在屏幕上的移动前后位置变化,进而动态调整内容元素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端,可能出现卡顿现象。

具体的优化策略请参考相关章节内容:

第三种方法是直接调用iScroll4第三方框架。


var scroll = new iScroll('parent', {
hScrollbar: false,
vScrollbar: true,
checkDOMChanges : true
});

该框架的官方网站地址为:http://cubiq.org/iscroll-4。

惯性缓动算法原理

接下来介绍惯性缓动功能的实现逻辑:

核心思路:获取手指在屏幕最后滑动时间段内的平均速度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);
});

此外,推荐几款在后续开发中常用的代码格式化与美化工具:

在线JavaScript代码美化、格式化工具: http://tools.jb51.net/code/js

JavaScript压缩/格式化/加密工具: http://tools.jb51.net/code/jscompress

json代码在线格式化/美化/压缩/编辑/转换工具: http://tools.jb51.net/code/jsoncodeformat

在线JSON代码检验、检验、美化、格式化工具: http://tools.jb51.net/code/json

更多关于jQuery相关内容感兴趣的读者可查看本站专题:《jQuery常用插件及用法总结》、《jquery中Ajax用法总结》、《jQuery表格(table)操作技巧汇总》、《jQuery拖拽特效与技巧总结》、《jQuery扩展技巧总结》、《jQuery常见经典特效汇总》、《jQuery动画与特效用法总结》及《jquery选择器用法总结》

希望本文所述对大家jQuery程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章