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

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

时间:2024-06-16 19:54:46浏览次数:10  
标签:loading const 触摸 全攻略 刷新 滑动 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~

标签:loading,const,触摸,全攻略,刷新,滑动,H5,手指
From: https://www.cnblogs.com/vigourice/p/18250533

相关文章

  • 【工具推荐】MobaXterm远程终端管理工具史上最全攻略,涉及下载、安装、字体等配置、解
    【强烈推荐】MobaXterm远程终端管理工具史上最全攻略,涉及下载、安装、字体等配置、解决中文乱码、Telnet/ssh/Serial使用教程、高级功能使用技巧等。MobaXterm是一个增强型的Windows终端。其为Windows桌面提供所有重要的远程网络终端工具(如SSH、X11、RDP、VNC、FTP、S......
  • webview和H5
    webview:chrome自带的工具 关键选项:Disablecache:不加载缓存,从零载入蓝色线:dom出现(可以开始点击)红色线:图片等资源已加载完成 Queueing:队列等待时间Stalled:在队列中停止请求Waiting:服务器响应时间ContentDownload:下载时间 手机浏览器性能分......
  • Redis实战指南:基础知识、实战技巧、应用场景及最佳实践全攻略
    背景在Java系统实现过程中,我们不可避免地会借助大量开源功能组件。然而,这些组件往往功能丰富且体系庞大,官方文档常常详尽至数百页。而在实际项目中,我们可能仅需使用其中的一小部分功能,这就造成了一个挑战:如何在有限的时间和精力下,高效地掌握并使用这些组件的核心功能,以实现......
  • 实现Token过期处理和刷新机制
    如何处理AccessToken过期并使用RefreshToken获取新的AccessToken解决方案:在登录成功时,服务器返回给客户端两个Token:AccessToken和RefreshToken。AccessToken用于访问受保护的资源,而RefreshToken用于获取新的AccessToken。将RefreshToken存储在客户端(例如,浏览器的C......
  • 【最新鸿蒙应用开发】——ArkWeb2——arkts与h5交互
    H5与端侧交互1.应用侧调用前端页面函数应用侧可以通过runJavaScript()方法调用前端页面的JavaScript相关函数。在下面的示例中,点击应用侧的“runJavaScript”按钮时,来触发前端页面的htmlTest()方法。前端页面代码。<!--index.html--><!DOCTYPEhtml><html><body>......
  • 最新AI系统+ChatGPT网站H5源码+AI绘画系统,DALL-E3文生图,详细图文搭建教程/文档分析/识
    目录一、文章前言系统文档 二、系统演示三、系统功能模块3.1AI全模型支持/插件系统AI模型提问文档分析​识图理解能力3.2GPts应用3.2.1GPTs应用3.2.2GPTs工作台3.2.3自定义创建预设应用3.3AI专业绘画3.3.1文生图/图生图(垫图)3.3.2 局部编辑重绘3.3.3 ......
  • 某东 h5st 4.7 逆向分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作......
  • H5可回溯方案
    Rrweb官关指南    H5可回溯方案浅析    Rrweb前端可回溯方案   Rrweb进行web录制以及回放   Rrweb录屏重放页面   Rrweb记录操作(txt文档上传阿里云)代码 用Java和rrweb构建一个可回溯系统   基于rrweb框架对web页面录制与回放    前端......
  • ch5 信息不对称与信息经济
    重点信息不对称的原因和类型委托代理关系的构成逆向选择道德风险课程目标掌握信息不对称的经典理论与应用;了解信息不对称的原因、类型和对市场交易的影响,知晓信息不对称的基本解决方案,明确委托代理的基本原理和方法;知道逆向选择、道德风险的基本概念和应用;了解信号机制......
  • 最新AI系统源码,ChatGPT运营网站H5系统源码,支持GPTs应用、AI绘画、文档分析、GPT语音对
    一、文章前言SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型+国内AI全模型。支持GPT-4o大模型、文档分析、识图图片理解、GPTs应用、GPT语音对话、联网提问、GPT-4全模型、DALL-E3文生图、GPT4-All联网搜索模型、思维导图、......