HTML5手机开发——滚动和惯性缓动_html 适配手机 允许滚动-程序员宅基地

技术标签: Html+Javascript  

1. 滚动

以下是三种实现方式:

1) 利用原生的css属性 overflow: scroll

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

Notice: 在androidbug, 滚动完后会回退到最顶端的内容区域,解决办法是使用后两种方式实现

2)js编程实现

思路:对比手指在屏幕上移动前后位置变化改变内容元素content

  1. 滚动

以下是三种实现方式:

1) 利用原生的css属性 overflow: scroll

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

Notice:

androidbug, 滚动完后会回退到最顶端的内容区域,解决办法是使用后两种方式实现

2)js 编程实现

思路:对比手指在屏幕上移动前后位置变化改变内容元素content的位置

第一步:设置parentoverflowhidden, 设置contentpositionrelative, top0;

第二步:监听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);
});
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wulex/article/details/100105694

智能推荐

Django的csrf豁免:解决CSRF验证失败,请求被中断问题_django注释中间件仍无法关闭csrf-程序员宅基地

文章浏览阅读1.2w次,点赞9次,收藏18次。文章目录一.CSRF介绍二.解决csrf的问题/csrf豁免一.CSRF介绍跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。这里推荐一篇文章,个人感觉写的不错:Python中_django注释中间件仍无法关闭csrf

三步共享WIN10的视频文件给电视盒子播放_电视盒子如何播放电脑上的资源-程序员宅基地

文章浏览阅读1.2w次,点赞3次,收藏10次。家里有一台电脑安装的WIN10,家里也有路由器,还有几个电视盒子接的电视机。本身是一个局域网络,所以不管有线还是无线,WIN10上有共享视频文件,其它设备都是可以播放的。WIN10共享视频文件,需要做2件事:一、打开SMB文件共享功能程序和功能->启用或关闭Windows功能->选中SMB1.0/CIFS File Sharing Support点确定后,WIN自动把这个S..._电视盒子如何播放电脑上的资源

功能十分强大的PDF阅读工具:Adobe Acrobat DC编辑器下载-程序员宅基地

文章浏览阅读332次,点赞7次,收藏11次。是由Adobe公司推出的一款功能十分强大的PDF阅读工具,Adobe Acrobat DC是当今PDF文件最完美的解析工具,它不仅可以让用户查看PDF文件,还可以轻松地制作PDF文件,并对其进行注释、编辑、导出等操作。Adobe Acrobat DC还能利用ps的图像编辑功能。p=2842 (访问密码: 2842)解压密码:www.jsafx.com。

MII接口全家福_mii tx clock-程序员宅基地

文章浏览阅读294次。简介: MII是英文Medium Independent Interface的缩写,翻译成中文是“介质独立接口”,该接口一般应用于MAC层和PHY层之间的以太网数据传输,也可叫数据接口。(MAC与PHY间的管理接口一般是MDIO) MII接口的类型有很多,常用的有MII、RMII、SMII、SSMII、SSSMII、GMII、RGMII、SGMII、TBI、RTBI、XGMII_mii tx clock

Fl Studio20 Win中文永久版(附安装教程)_fl 注册表补丁grid color.reg-程序员宅基地

文章浏览阅读913次。前言它的前身为FruityLoops,一款由Image-Line公司开发的数字音频工作站,是以样式(pattern)为元素的编曲软件。可使用VST;VSTi插件,还可以作为ReWire客户端。FL非常适合制作电子音乐。通过本篇文章提供的地址解压安装激活之后效果图如下:功能特色1、创建音乐视频:Visualizer视频发生器带有新的视频创建向导。可以从令人惊讶的视频模板大菜单中进行选择,并在视频预览中直接拖放和移动文本到其它图层。2、音符包络:VFX Envelope可以让你连续的.._fl 注册表补丁grid color.reg

【赠书第13期】边缘计算系统设计与实践-程序员宅基地

文章浏览阅读1w次,点赞123次,收藏101次。探秘云边端,揭示原理,实践边缘技术。

随便推点

深入分析synchronized的实现原理_java中synchronized实现原理-程序员宅基地

文章浏览阅读2.8w次,点赞16次,收藏76次。记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。 诚然,随着Javs _java中synchronized实现原理

Nosql数据库的分类及应用场景_nosql模型及应用-程序员宅基地

文章浏览阅读5.1k次,点赞3次,收藏10次。一网打尽当下NoSQL类型、适用场景及使用公司 NoSQL开篇——为什么要使用NoSQL(注意评论) nosql是not only sql的意思。是近今年新发展起来的存储系统。当前使用最多的是key-value模型,是一种非关系型数据库,主要是解决是海量数据下的数据库性能和扩展能力。它最大的特点在于要求的数据量大,对事物的要求低。 NoSQL 它打破了长久以来关系型数_nosql模型及应用

如何注册谷歌开发者账号-程序员宅基地

文章浏览阅读576次,点赞7次,收藏8次。4.按照提示,一步一步完成信息的填写,到最后需要支付25美金,需要上传一张信用卡进行支付。5.支付完成之后,首页如果显示需要验证就进行验证。1.首先你必须有一个普通的谷歌账号。6.验证完成后就是等待啦!2.注册成功之后,进入。_谷歌开发者账号

域名接入CloudFlare_华纳云域名接入cloudflarer-程序员宅基地

文章浏览阅读726次,点赞6次,收藏10次。如果我想要通过Cloudflare的https访问,只要单独配置为灵活即可。由于配置了Cloudflare,会间接导致实际的用户客户端ip拿不到。因为我的根域名是有阿里云证书的,且服务器强制重写http到https,所以选择严格。3.) 查看并明确DNS记录,其中服务的解析地址填写自己实际的服务器ip。4.) 去域名管理控制台,移除旧DNS服务器,添加新DNS服务器。6.) 配置并开启SSL,使用的Cloudflare颁发的证书。准备就绪,说是24小时,实际等待也就半个点,直接进行测试一下。_华纳云域名接入cloudflarer

java计算机毕业设计校园疫情防控健康打卡小程序【附源码+远程部署+程序+mysql】-程序员宅基地

文章浏览阅读194次,点赞3次,收藏5次。通过每日健康打卡,学校可以迅速掌握学生的体温、症状、接触史等关键信息,及时识别出异常情况,减少疫情扩散的风险。学生群体的健康安全直接关系到家庭和社会的稳定,因此,如何有效监控和保障学生的健康状况成为学校管理的一大挑战。随着科技的进步,数字化手段被广泛应用于疫情防控中,其中,健康打卡小程序作为一种便捷的信息化工具,能够实时收集学生的健康信息和行程轨迹,为校园疫情防控提供了新的思路和方法。通过这种小程序,学校可以快速了解学生的健康状况,及时发现潜在的风险,并采取相应的预防措施,从而有效遏制疫情在校园内的传播。

基于Docker镜像elleflorio/svn-server搭建SVN服务器-程序员宅基地

文章浏览阅读5.6k次,点赞4次,收藏13次。基于Docker镜像elleflorio/svn-server搭建SVN服务器搭建过程如下:1、在宿主机创建svn相关目录2、拉取最新镜像3、运行容器4、复制容器中SVN配置文件至宿主机5、停止并移除容器6、运行容器并挂载配置及SVN目录7、查看是否运行成功8、修改容器内的httpd.conf中的ServerName9、配置svnadmin10、总结搭建过程如下:本文中是基于dcoker镜像e..._elleflorio/svn-server