如何实现上拉加载和下拉刷新

article/2025/10/12 18:58:10

下拉刷新和上拉加载这两种交互⽅式通常出现在移动端中

本质上等同于PC⽹⻚中的分⻚,只是交互形式不同

开源社区也有很多优秀的解决⽅案,如 iscroll 、 better-scroll 、 pulltorefresh.js 库等等 这些第三⽅库使⽤起来⾮常便捷

我们通过原⽣的⽅式实现⼀次上拉加载,下拉刷新,有助于对第三⽅库有更好的理解与使⽤

实现原理

上拉加载及下拉刷新都依赖于⽤户交互

最重要的是要理解在什么场景,什么时机下触发交互动作

上拉加载 

首先先看图

上拉加载的本质是⻚⾯触底,或者快要触底时的动作

判断⻚⾯触底我们需要先了解⼀下下⾯⼏个属性

  • scrollTop :滚动视窗的⾼度距离 window 顶部的距离,它会随着往上滚动⽽不断增加,初始 值是0,它是⼀个变化的值
  • clientHeight :它是⼀个定值,表示屏幕可视区域的⾼度;
  • scrollHeight :⻚⾯不能滚动时也是存在的,此时scrollHeight等于clientHeight。scrollHeight表 示 body 所有元素的总⻓度(包括body元素⾃身的padding

 综上我们得出一个触底公式

 scrollTop + clientHeight >= scrollHeight

简单实现

let clientHeight = document.documentElement.clientHeight; //浏览器⾼度
let scrollHeight = document.body.scrollHeight;
let scrollTop = document.documentElement.scrollTop;
let distance = 50; //距离视窗还有50的时候,开始触发;
if ((scrollTop + clientHeight) >= (scrollHeight - distance)) {console.log("开始加载数据");
}

下拉刷新

下拉刷新的本质是⻚⾯本身置于顶部时,⽤户下拉时需要触发的动作

关于下拉刷新的原⽣实现,主要分成三步:

  • 监听原⽣ touchstart 事件,记录其初始位置的值, e.touches[0].pageY ;
  • 监听原⽣ touchmove 事件,记录并计算当前滑动的位置值与初始位置值的差值,⼤于 0 表示向 下拉动,并借助CSS3的 translateY 属性使元素跟随⼿势向下滑动对应的差值,同时也应设置⼀ 个允许滑动的最⼤值
  • 监听原⽣ touchend 事件,若此时元素滑动达到最⼤值,则触发 callback ,同时 将 translateY 重设为 0 ,元素回到初始位置

举个例子: 

Html 结构如下:

<main><p class="refreshText"></p ><ul id="refreshContainer"><li>111</li><li>222</li><li>333</li><li>444</li><li>555</li>...</ul>
</main>

监听 touchstart 事件,记录初始的值

var _element = document.getElementById('refreshContainer'),_refreshText = document.querySelector('.refreshText'),_startPos = 0, // 初始的值_transitionHeight = 0; // 移动的距离
_element.addEventListener('touchstart', function(e) {_startPos = e.touches[0].pageY; // 记录初始位置_element.style.position = 'relative';_element.style.transition = 'transform 0s';
}, false);

监听 touchmove 移动事件,记录滑动差值

_element.addEventListener('touchmove', function(e) {// e.touches[0].pageY 当前位置_transitionHeight = e.touches[0].pageY - _startPos; // 记录差值if (_transitionHeight > 0 && _transitionHeight < 60) {_refreshText.innerText = '下拉刷新';_element.style.transform = 'translateY('+_transitionHeight+'px)';if (_transitionHeight > 55) {_refreshText.innerText = '释放更新';}} 
}, false);

最后,就是监听 touchend 离开的事件

_element.addEventListener('touchend', function(e) {_element.style.transition = 'transform 0.5s ease 1s';_element.style.transform = 'translateY(0px)';_refreshText.innerText = '更新中...';// todo...
}, false);

从上⾯可以看到,在下拉到松⼿的过程中,经历了三个阶段:

  • 当前⼿势滑动位置与初始位置差值⼤于零时,提示正在进⾏下拉刷新操作
  • 下拉到⼀定值时,显示松⼿释放后的操作提示
  • 下拉到达设定最⼤值松⼿时,执⾏回调,提示正在进⾏更新操作

案例 

在实际开发中,我们更多的是使⽤第三⽅库,下⾯以 better-scroll 进⾏举例:

HTML结构

<div id="position-wrapper"><div><p class="refresh">下拉刷新</p ><div class="position-list"><!--列表内容--></div><p class="more">查看更多</p ></div>
</div>

实例化上拉下拉插件,通过 use 来注册插件

import BScroll from "@better-scroll/core";
import PullDown from "@better-scroll/pull-down";
import PullUp from '@better-scroll/pull-up';
BScroll.use(PullDown);
BScroll.use(PullUp);

实例化 BetterScroll ,并传⼊相关的参数

let pageNo = 1,pageSize = 10,dataList = [],isMore = true; 
var scroll= new BScroll("#position-wrapper",{scrollY:true,//垂直⽅向滚动click:true,//默认会阻⽌浏览器的原⽣click事件,如果需要点击,这⾥要设为truepullUpLoad:true,//上拉加载更多pullDownRefresh:{threshold:50,//触发pullingDown事件的位置stop:0//下拉回弹后停留的位置}
});
//监听下拉刷新
scroll.on("pullingDown",pullingDownHandler);
//监测实时滚动
scroll.on("scroll",scrollHandler);
//上拉加载更多
scroll.on("pullingUp",pullingUpHandler);
async function pullingDownHandler(){dataList=[];pageNo=1;isMore=true;$(".more").text("查看更多");await getlist();//请求数据scroll.finishPullDown();//每次下拉结束后,需要执⾏这个操作scroll.refresh();//当滚动区域的dom结构有变化时,需要执⾏这个操作
}
async function pullingUpHandler(){if(!isMore){$(".more").text("没有更多数据了");scroll.finishPullUp();//每次上拉结束后,需要执⾏这个操作return;}pageNo++;await this.getlist();//请求数据scroll.finishPullUp();//每次上拉结束后,需要执⾏这个操作scroll.refresh();//当滚动区域的dom结构有变化时,需要执⾏这个操作 
}
function scrollHandler(){if(this.y>50) $('.refresh').text("松⼿开始加载");else $('.refresh').text("下拉刷新");
}
function getlist(){//返回的数据let result=....;dataList=dataList.concat(result);//判断是否已加载完if(result.length<pageSize) isMore=false;//将dataList渲染到html内容中
}

注意点:

使⽤ better-scroll 实现下拉刷新、上拉加载时要注意以下⼏点:

  • wrapper ⾥必须只有⼀个⼦元素
  • ⼦元素的⾼度要⽐ wrapper 要⾼
  • 使⽤的时候,要确定 DOM 元素是否已经⽣成,必须要等到 DOM 渲染完成后,再 new BScroll()
  • 滚动区域的 DOM 元素结构有变化后,需要执⾏刷新 refresh()
  • 上拉或者下拉,结束后,需要执⾏ finishPullUp() 或者 finishPullDown() ,否则将不会执 ⾏下次操作
  • better-scroll ,默认会阻⽌浏览器的原⽣ click 事件,如果滚动内容区要添加点击事件,需 要在实例化属性⾥设置 click:true

小结: 

下拉刷新、上拉加载原理本身都很简单,真正复杂的是封装过程中,要考虑的兼容性、易⽤性、性能等 诸多细节


http://chatgpt.dhexx.cn/article/EUK24voA.shtml

相关文章

ComposeUI——下拉刷新+上拉加载(一、简单封装)

前言&#xff1a;ComposeUI是将来开发的趋势&#xff0c;本人也在对它进行学习&#xff0c;会把踩过的坑一一记录下来&#xff0c;希望能对大家有帮助。话不多说&#xff0c;直接开干。 目录 下拉刷新 1、引入依赖库 2、使用方法 上拉加载 1、先看用法&#xff08;结合下…

Flutter 下拉刷新、上拉加载

Flutter 下拉刷新、上拉加载有很多第三方插件&#xff0c;本文使用插件为&#xff1a;pull_to_refresh 目前pull_to_refresh在pub.dev上的使用情况&#xff1a; 刷新header的类型: ClassicHeader const ClassicHeader({Key? key,RefreshStyle refreshStyle: RefreshStyle.…

BaseQuickAdapter上拉加载功能实现

最近使用BaseQuickAdapter进行RecyclerView 的Adapter的数据绑定显示。 实现上拉加载与下拉刷新功能&#xff0c;遇到如下问题&#xff1a; 1、首先是实现下拉刷新、下拉加载的监听&#xff08;xml布局就不贴出来了&#xff09;&#xff1a; 2、现在贴出来错误的处理方式&…

android 官方上拉,手把手教你实现RecyclerView的下拉刷新和上拉加载更多

纵观多数App&#xff0c;下拉刷新和上拉加载更多是很常见的功能&#xff0c;但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新&#xff0c;上拉加载更多还要自己做。 基于RecyclerView简单封装了这两个操作&#xff0c;下拉刷新支持LinearLayoutManager、GridLayoutManager…

uniapp下拉刷新上拉加载

一、需求 留言板主页&#xff0c;显示所有的留言信息&#xff0c;带有分页功能&#xff1b;上拉加载数据&#xff0c;下拉刷新数据二、代码 1、pages.json 2、messageBoard.vue 用了 uniapp 提供的组件&#xff1a; uni-load-more.vue <uni-load-more :status"load…

jquery 实现上拉加载功能

emmmm&#xff0c;看到了以前自己的写的代码&#xff0c;用jquery实现的上拉加载&#xff0c;顺便修复了以前漏下的bug&#xff0c;感觉可以记录一波。 好的先上图&#xff0c; 好的首先关注console控制台&#xff0c;再来就是右图的内容&#xff0c;页面上初始仅有两个div 接…

微信小程序下拉刷新、上拉加载

微信小程序官方没有给出具体的下拉刷新和上拉加载组件&#xff0c;我们可以基于小程序原生组件scroll-view的扩展与封装,实现简单的上拉加载、下拉刷新组件。 1. 封装组件 // components/customPullDown/index.js Component({options: {multipleSlots: true},properties: {ch…

uniapp局部上拉加载数据

一、页面局部实现上拉加载数据 只有评论区可以上拉加载数据&#xff0c;网上找到了 vue-infinite-scroll二、使用 官方示例 1、 npm 加载依赖 npm install vue-infinite-scroll --save2、 单个页面引用 import infiniteScroll from vue-infinite-scrollexport default {dire…

【Compose】亲手封装一个简单灵活的下拉刷新上拉加载 Compose Layout

Compose 的下拉刷新有现成的 Material 库可以直接使用&#xff0c;非常简单方便。 但是上拉加载目前没看到有封装的特别好的库&#xff0c;Paging 有些场景无法满足&#xff0c;而且上拉加载也是个比较简单的功能&#xff0c;没必要再去依赖一个质量未知的库。我们可以基于目前…

如何实现上拉加载,下拉刷新?

如何实现上拉加载下拉刷新&#xff1f; 实现原理上拉加载下拉刷新 实现原理 上拉加载及下拉刷新都依赖于用户交互 最重要的是要理解在什么场景&#xff0c;什么时机下触发交互动作 上拉加载 首先可以看一张图 上拉加载的本质是页面触底&#xff0c;或者快要触底时的动作 判…

【前端知识之JS】如何实现上拉加载和下拉刷新

前言 本系列主要整理前端面试中需要掌握的知识点。本节介绍如何实现上拉加载和下拉刷新。 文章目录 前言一、介绍二、实现原理1、上拉加载2、下拉刷新 一、介绍 下拉刷新和上拉加载这两种交互方式通常出现在移动端中&#xff1b;本质上等同于PC网页中的分页&#xff0c;只是交…

大数据和人工智能到底是什么关系

大数据和人工智能的关系&#xff0c;首先要说什么是大数据。这些年来&#xff0c;大数据先是被神化&#xff0c;继而又被妖魔化&#xff0c;到了今天&#xff0c;其实谁也不知道别人所谓的大数据指的是什么。有时候大数据的定义里既有平台&#xff08;硬件&#xff09;又有分析…

大数据和人工智能AI的联系和区别

大数据和人工智能两个词是我们现在频繁听到的两个词汇&#xff0c;那么这两者之间到底有什么联系 首先我们要了解到什么是大数据&#xff1f;什么是人工智能&#xff1f;大数据就是一种规模大到在获取、存储、管理、分析方面大大超出了传统数据库软件工具能力范围的数据集合&…

人工智能、机器学习、深度学习 三者关系

目录 1、AI ML DL关系 2、发展历程 2.1、人工智能&#xff08;ArtificiaI Intelligence&#xff09; 2.2、机器学习&#xff08;Machine Learning&#xff09; 2.3、深度学习&#xff08;Deep Learning&#xff09; 1、AI ML DL关系 为了赋予计算机以人类的理解能力与逻辑…

云计算、大数据和人工智能三者到底什么关系

今天跟大家讲讲云计算、大数据和人工智能。为什么讲这三个东西呢&#xff1f;因为这三个东西现在非常火&#xff0c;并且它们之间好像互相有关系&#xff1a;一般谈云计算的时候会提到大数据、谈人工智能的时候会提大数据、谈人工智能的时候会提云计算……感觉三者之间相辅相成…

人工智能和大数据分析之间,主要有什么区别

首先来看看认知计算和人工智能的区别 人工智能的概念已经有二十多年&#xff0c;人工智能从历史和研究角度来讲主要目的是为了让机器表现的更像人类&#xff0c;我们称之为Intelligent Behavior。IBM的认知计算从技术角度上讲和AI是有很多共性的地方&#xff0c;比如机器学习&…

人工智能与大数据的完美结合

人工智能(AI)已经存在几十年了。然而&#xff0c;最近随着“大数据”的出现&#xff0c;它得到了越来越多的关注。维基百科对人工智能的释义如下: 在计算机科学中&#xff0c;人工智能研究的领域将自己定义为“智能代理AI和大数据&#xff1a;完美结合”的研究&#xff1a;任何…

大数据和人工智能的概念

大数据和人工智能的概念 概述大数据和人工智能领域的一些热门趋势。我们将看到世界如何通过数字化而改变&#xff0c;从而导致消费和工业领域的大数据现象&#xff1b;了解到数据量呈指数级增长&#xff0c;从太字节到艾字节再到泽字节&#xff1b;意识到计算机的处理能力增加…

云计算、大数据和人工智能之间的关系

大家好&#xff0c;这里是抖码课堂&#xff0c;抖码课堂专注提升互联网技术人的软硬实力。 这篇文章我们从下面的内容来聊下云计算、人工智能、大数据技术三者之间的关系 探讨什么是云计算&#xff0c;在这里分别探讨云计算的 IaaS、PaaS 以及 SaaS 探讨云计算和大数据技术之…

大数据属于人工智能吗?什么是大数据?

对于“大数据”(Big data)研究机构Gartner给出了这样的定义。“大数据”是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力来适应海量、高增长率和多样化的信息资产。大数据属于人工智能吗&#xff1f;本篇来解答一下这个问题。 大数据属于人工智能吗&#xff…