轻松实现H5页面下拉刷新:滑动触发、高度提示与数据刷新全攻略

前段时间在做小程序到H5的迁移,其中小程序中下拉刷新的功能引起了产品的注意。他说到,哎,我们迁移后的H5页面怎么没有下拉刷新,于是乎,我就急忙将这部分的内容给填上。

本来是计划使用成熟的组件库来实现,尝试之后发现这些组件和我们H5页面的其他逻辑有冲突(H5还有吸顶、锚点、滑动高亮、横向滚动),小小H5页面上承载了太多的功能,兼容起来非常麻烦,想着下拉刷新功能也不复杂,干脆我自己写一个好了。

流程图示

正常数据展示状态 --> 手指触摸屏幕下拉 --> 手指松开 --> 数据获取 --> 恢复正常数据展示状态

在这里插入图片描述

功能梳理

要实现这个功能,主要分为两部分。

监听手指触摸事件

通过监听事件,我们可以得知以下的数据

  • 手指滑动的时机(手指开始触摸,结束触摸时间)
  • 滑动方向(是横向滑动还是纵向滑动)
  • 操作轨迹(手指操作从下往上还是从上往下滑动)
  • 是否首屏(如果非首屏进行滑动时是正常滑动操作)
    只有在向下滑动首屏非加载状态纵向滚动并且有高度时,才能进行上述刷新流程。
css 和 提示文案
  • 手指按住屏幕由上往下滑动未松开时,展示滑动的高度和提示**【释放刷新】**文案
  • 手指松开后高度回弹,显示**【数据更新中】**文案
  • 数据请求接口成功后,显示**【更新成功】**文案,loading 内容和图标缓缓消失

具体实现

触摸的步骤可以分为: 手指按下(开始触摸)、手指移动不离开屏幕(触摸中)、手指离开屏幕(触摸结束),正好对应着三个 js 原生事件,touchstarttouchmovetouchend

触摸事件执行时机

touchstart 和 touchmove 在一次触摸流程只会执行一次,标志着开始和结束,但是 touchmove 不一样,只要你的手指还在屏幕上滑动没有松开,就会一直执行。如下图的输出的执行次数一样。

在这里插入图片描述

下拉元素绑定

首先需要给需要设置下拉刷新的区域绑定上这些事件,对于我们业务场景来说,头部区域无论你如何操作,都需要保留展示的,那么我们只需要将事件绑定到下方开始显示下拉刷新的区域。

// html元素
<div className="refreshWrap">{/* 下拉时文字提示 */}<div className={`pullDownContent`} style={{ height: pullDownHeight }}>{loading ? "" : "释放刷新"}</div>{/* 加载时动画 */}<div className={`loadingFlex ${loading ? "" : "loadingHidden"}`}><div className="flexCenter"><div className="loadingRing" /><div className="loadingText">{loading ? "数据更新中..." : "更新成功"}</div></div></div><div className="middleArea">刷新区域下方内容区域</div>
</div>// js 绑定
const pullDownClassName = ".refreshWrap";bindPullDown() {const pulldownElement = document.querySelector(pullDownClassName);pulldownElement.addEventListener("touchstart", this.bindTouchstart);pulldownElement.addEventListener("touchmove", this.bindTouchMove);pulldownElement.addEventListener("touchend", this.bindTouched);
}

在这里插入图片描述

触摸开始

手指触摸到屏幕的逻辑非常简单,使用 startTouch 对象来记录触摸的位置,包含 x 、y 轴。

bindTouchstart = (event) => {this.startTouch = event.touches[0];};

在这里插入图片描述

触摸中

用户触摸中需要给他一个反馈,随着下拉的距离,屏幕上圈出的下拉区域会随之变大(下拉展示的区域会设置一个最大高度,如果能无限扩大展示不好看)

在这里插入图片描述

endTouch 来保存触摸中的坐标值,因为触摸中的事件会执行多次,所以 endTouch 也会不断的更新,用来更新下拉时滑动的高度。

 bindTouchMove = (event) => {const { loading } = this.state;this.endTouch = event.touches[0];if (!loading && this.isInOneScreenPull() && this.isVerticalSliding()) {const pullDownHeight = this.getPullDownHeight();this.setState({pullDownHeight,});}};

根据 endTouch 的值可以判断出滑动距离、横向还是纵向滑动,滑动的高度、再获取滑动元素是否在首屏。

// 判断滑动的距离
calcDeltaY = () => Math.abs(this.endTouch.pageY - this.startTouch.pageY);// 判断是否纵向滚动
isVerticalSliding = () => {const deltaY = this.calcDeltaY();const deltaX = Math.abs(this.endTouch.pageX - this.startTouch.pageX);if (deltaY > deltaX && deltaY > 50) return true;
};// 下拉展示高度最多展示为100,不能让加载区域无限制的扩大
getPullDownHeight = () => {const deltaY = this.calcDeltaY();return Math.min(deltaY, 100);
};// 是否在首屏
isInOneScreenPull() {const pulldownElement = document.querySelector(pullDownClassName);return pulldownElement.scrollTop <= 0;
}
触摸结束

触摸结束时,将 pulldownHeight 设置为0,异步加载数据,加载数据时设置变量 loading 表示开始更新、结束更新,防止不停的下拉刷新调用接口。

bindTouched = (e) => {const { loading, pullDownHeight } = this.state;// 首屏、非加载状态、纵向滚动有高度时if (!loading && pullDownHeight) {this.setState({pullDownHeight: 0,});this.getData();// 重置触摸Y轴坐标点this.startTouch = {};this.endTouch = {};}
};
平滑过渡动画

当下拉高度发生变化时,直接修改高度效果会比较生硬,使用 css transition 属性进行平滑过渡、animation 设置动画缓慢进入/消失。

.pullDownContent {display: flex;align-items: flex-end;justify-content: center;font-size: 12px;color: rgba(0, 0, 0, 0.25);margin: auto;transition: height 0.3s ease-out; /* 平滑过渡效果 */overflow: hidden;
}.loadingHidden {animation: shrinkHeight 1s forwards;
}@keyframes shrinkHeight {100% {height: 0;opacity: 0;overflow: hidden;}
}

完整代码

以上便是滑动触发、高度提示、数据刷新的下拉刷新功能解析,完整代码我放在了 github 上,戳 drop-down-refresh 可查看,欢迎大家点个 star~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/28274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows修改CMD窗口编码为UTF-8

windows下的cmd的默认编码是GBK编码&#xff0c;有时可能造成乱码问题&#xff0c;下面是我找到的两种更换编码方式为UTF-8的方法。 1、临时修改 &#xff08;1&#xff09;先进入cmd命令窗口&#xff08;快捷键win键R&#xff09; &#xff08;2&#xff09;直接输入“chcp…

畅想智能美颜工具的未来:美颜SDK技术详解

美颜SDK作为技术的核心&#xff0c;承载了美颜工具的实现和创新。本篇文章&#xff0c;小编将深入探讨美颜SDK技术的细节。 一、技术原理 美颜SDK是一种软件开发工具包&#xff0c;集成了一系列图像处理算法和技术&#xff0c;旨在实现对照片和视频中人物的实时美化。其主要技…

逢3必过报数游戏-第13届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第84讲。 逢3必过报数游戏&…

c++_0基础_讲解7 练习

这一讲我为大家准备了几道题目&#xff0c;大家试着独自做一下&#xff08;可能来自不同网站&#xff09; 整数大小比较 - 洛谷 题目描述 输入两个整数&#xff0c;比较它们的大小。若 x>yx>y &#xff0c;输出 > &#xff1b;若 xyxy &#xff0c;输出 &#xff…

---异常---

我们在运行程序时总遇到各种与报错&#xff0c;数组越界&#xff0c;空指针的引用&#xff0c;这些在java中都称为异常 对于不同的错误都具有一个与他对应的异常类来秒描述 这是对于数组越界这个类里有的方法&#xff0c;这些是描述异常的 在java中有一个完整的描述异常的类的…

嵌入式数据库的一般架构

嵌入式数据库的架构与应用对象紧密相关&#xff0c;其架构是以内存、文件和网络等三种方式为主。 1.基于内存的数据库系统 基于内存的数据库系统中比较典型的产品是每个McObject公司的eXtremeDB嵌入式数据库&#xff0c;2013年3月推出5.0版&#xff0c;它采用内存数据结构&…

2024年黑龙江省特岗招聘公告出了!!!

2024年黑龙江省农村义务教育阶段学校特设岗位教师招聘822人公告 (1、网上报名 时间&#xff1a;6月17日9&#xff1a;00—6月22日17&#xff1a;00。 网址&#xff1a; https&#xff1a;//sfyz.hljea.org.cn&#xff1a;7006/tgjs 2、网上资格审查 资格审查时间&#xff1a;6月…

英语学习笔记36——Where ... ?

Where … ? ……在哪里&#xff1f; 词汇 Vocabulary beside prep. 在……旁边 同义词&#xff1a; near by 构成&#xff1a;be side side n. 边 搭配&#xff1a;side walk 人行道 例句&#xff1a;Bobby在我旁边。    Bobby is beside me. off prep. 离开&#xff…

C/C++中内存开辟与柔性数组

C/C中内存的开辟 在C中&#xff0c;我们都知道有三个区&#xff1a; 1. 栈区&#xff08;stack&#xff09;&#xff1a;在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指…

使用itextPDF实现PDF电子公章工具类

一、制作公章 在线网站&#xff1a;印章生成器 - Kalvin在线工具 (kalvinbg.cn) 然后对公章进行下载保存 盖章图片&#xff1a; 二、生成数字签名 2.1&#xff1a; java工具keytool生成p12数字证书文件 Keytool是用于管理和证书的工具&#xff0c;位于%JAVA_HOME%/bin目录。…

代码随想录——组合总数Ⅲ(Leetcode216)

题目链接 回溯 class Solution {List<List<Integer>> res new ArrayList<List<Integer>>();List<Integer> list new ArrayList<Integer>();public List<List<Integer>> combinationSum3(int k, int n) {backtracking(k, …

揭秘最强气象武器的库,SPEI-Python不可思议之处.

spei-python是一个专门用于计算标准化降水蒸散指数&#xff08;Standardized Precipitation Evapotranspiration Index,SPEI&#xff09;的Python库.SPEI是一种综合考虑降水和潜在蒸散发的干旱指数,用于评估干旱的严重程度和持续时间. 安装 ## 可以使用 pip 来安装 spei-pyth…

【EtherCAT电机板】CiA402增加cst模式

在EtherCAT电机板上实现cst功能&#xff0c;在xml中增加cst相关pdo&#xff0c;在402程序增加cst模式。 1、XML配置修改 cst模式需要用到目标转矩和反馈实际转矩PDO&#xff0c;结合CiA402手册&#xff0c;这两个PDO对应的索引号分别为&#xff1a;0x6071&#xff08;Target t…

基于微信小程序的在线答题小程序设计与实现

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

JavaFX VBox

VBox布局将子节点堆叠在垂直列中。新添加的子节点被放置在上一个子节点的下面。默认情况下&#xff0c;VBox尊重子节点的首选宽度和高度。 当父节点不可调整大小时&#xff0c;例如Group节点&#xff0c;最大垂直列的宽度基于具有最大优选宽度的节点。 默认情况下&#xff0c;…

分数布朗运动FBM期权定价模型

BS定价模型和蒙特卡洛模拟期权定价方法都 假设标的资产价格的对数服从布朗运动 &#xff0e; 但是实际 的金融市场中标的资产价格运动过程具有 “尖峰厚尾 ” 现象 &#xff0c; 运用分数布朗运动 &#xff08;FBM &#xff09;来刻画标的资产 价格的运动过程可能更加合适。 …

单列集合顶层接口Collection及五类遍历方式(迭代器)

collection add方法细节&#xff1a; remove方法细节&#xff1a; contains方法细节&#xff1a; 如果集合中存储的是自定义对象, student之类的, 也想通过contains进行判断, 就必须在javaBean中重写equals方法 contains在arrayList中源代码&#xff1a;在底层调用了equals方…

电路笔记 :LM3481MM/NOPB升压模块,升压电路原理

LM3481MM/NOPB LM3481MM/NOPB 是德州仪器&#xff08;Texas Instruments&#xff09;的一款广泛应用的DC-DC控制器&#xff0c;常用于电源管理应用&#xff0c;特别是在需要升压&#xff08;boost&#xff09;、反激&#xff08;flyback&#xff09;、SEPIC或反向配置的场合。…

python读取excel导入数据库

一、环境准备&#xff0c;安装包 pip install pandas openpyxl sqlalchemy二、数据准备 三、代码编写 from sqlalchemy import create_engine import pandas as pdclass GDPDataImporter:def __init__(self, db_type, dbapi, host, port, database, username, password):&quo…

【数据库编程-SQLite3(二)】API-增删改查基础函数-(含源码)

学习分享 1、sqlite3_exec函数1.1、使用sqlite3_exec进行【查】操作1.1.1、callback函数 1.2、使用sqlite3_exec进行【增、删、改】操作 2、sqlite3_get_table函数2.1、使用sqlite3_get_table函数进行【查】操作 1、sqlite3_exec函数 1.1、使用sqlite3_exec进行【查】操作 由于…