react

前言

最近在写的项目中有上拉加载更多的需求。抽空就来写一篇文章。
上拉加载更多,下拉刷新,在原生 App 上经常都用到,既符合用户的使用习惯,也有很多成熟的库可以直接拿来使用。那么在WebApp中怎么实现呢?今天就我们就探讨一下。

一、思路

上拉刷新的可以通过判断某个点到窗口顶部的距离的值与浏览器窗口高度的值的大小来实现。假如说标识点在 WebApp 的底部,我们可以通过 js API Element.getBoundingClientRect().top 拿到它到屏幕顶部的距离,假如说是 200px 。同样的,可以利用 window.screen.heligh 拿到屏幕的高度,假如是 190px 。页面上滑,标志点到屏幕顶部的距离就会变小(这是废话…)。当距顶部距离小于190px时,调用加载数据的函数,就实现了上拉加载更多的功能。下拉刷新的逻辑与此大同小异,就不赘述了。另外,为了在上下滑网页时,需要对网页滚动进行监听,以保证我们对比的函数能够被触发。

二、实现

接下来就以 react.js 为例来写一个DEOM 实现一下。

准备工作

  1. create-react-app demo 创建一个名为 demo 的项目。
  2. cd demo && yarn start 启动程序。
  3. 打开 demo/src/App.js 修改代码如下。
import React, { Component } from 'react';
import './App.css';class App extends Component {constructor(props) {super(props);this.state = ({data: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],isLoadingMore: false});}render() {return (<div><div className="App">{this.state.data.map((item, index) => (<li key={index} className="li-item">{item}</li>))}</div><div className="loadMore" ref="wrapper" onClick={this.loadMoreDataFn.bind(this, this)}>加载更多</div></div>);}
}export default App;
  1. 修改 demo/src/App.css如下
.App {width: 100%;
}.li-item {height: 100px;display: flex;justify-content: center;align-items: center;
}.loadMore {display: flex;justify-content: center;align-items: center;height: 50px;border: 1px; border-style: solid;border-color: red;
}
  1. 浏览器打开 http://localhost:3000/,单击右键,检查,toggle device bar,让 chrome 模拟在手机上的效果。我们应该看到如下的页面。

三、实现逻辑

在 react 中,操作dom时一般用 ref。因此给“加载更多”所在 div 设置ref='wrapper',在 componentDidMount 方法中来实现业务逻辑。此处不明白为什么在此周期操作的同学应该再去看一遍 react 的LifeCycle。

在 componentDidMount 中,先定义一个变量用来保存dom。
const wparrer = this.refs.wrapper; 定义一个变量,用来降低屏幕滚动监听的频率。let timeCount;

接下来定义一个函数,内容如下:

function callback() {const top = wrapper.getBoundingClientRect().top;const windowHeight = window.screen.height;if (top && top < windowHeight) {// 当 wrapper 已经被滚动到页面可视范围之内触发loadMoreDataFn(that);}
}

top保存的是“加载更多”那个div距屏幕顶部的距离。Element.getBoundingClinentRect()的使用见MDN - Element.getBoundingClinentRect。
windowHeight保存的就是窗口的高度。通过对比top与windowHeight的高度,来调用加载更多的函数。

接下来我们再给屏幕滚动设置一个监听事件:

window.addEventListener('scroll', function () {if (this.state.isLoadingMore) {return ;}if (timeCount) {clearTimeout(timeCount);}timeCount = setTimeout(callback, 50);}.bind(this), false);

通过上述代码,就可以对屏幕滚动进行监听,timeCount变量是用来做延时的,检测到屏幕滚动后,延时50ms进行下一次检测。优化体验,也保证了性能。

loadMoreDataFn 在本文中,为了实现上拉加载更多的效果,此处写一个操作数组的逻辑,将一些数据放到this.state.data之后。当然,实际的开发中,也是这样做,不过合并的数据是 fetch 从 api 获取的。

  loadMoreDataFn(that) {that.setState({data: that.state.data.concat(['E', 'c', 'h', 'o'])})}

四、完整的代码

demo/src/App.jsx:

import React, { Component } from 'react';
import './App.css';class App extends Component {constructor(props) {super(props);this.state = ({data: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],isLoadingMore: false});}render() {return (<div><div className="App">{this.state.data.map((item, index) => (<li key={index} className="li-item">{item}</li>))}</div><div className="loadMore" ref="wrapper" onClick={this.loadMoreDataFn.bind(this, this)}>加载更多</div></div>);}componentDidMount() {const wrapper = this.refs.wrapper;const loadMoreDataFn = this.loadMoreDataFn;const that = this; // 为解决不同context的问题let timeCount;function callback() {const top = wrapper.getBoundingClientRect().top;const windowHeight = window.screen.height;if (top && top < windowHeight) {// 当 wrapper 已经被滚动到页面可视范围之内触发loadMoreDataFn(that);}}window.addEventListener('scroll', function () {if (this.state.isLoadingMore) {return ;}if (timeCount) {clearTimeout(timeCount);}timeCount = setTimeout(callback, 50);}.bind(this), false);}loadMoreDataFn(that) {that.setState({data: that.state.data.concat(['E', 'c', 'h', 'o'])})}
}export default App;

demo/src/App.css:

.App {width: 100%;
}.li-item {height: 100px;display: flex;justify-content: center;align-items: center;
}.loadMore {display: flex;justify-content: center;align-items: center;height: 50px;border: 1px; border-style: solid;border-color: red;
}

react上拉加载更多相关推荐

  1. react-native ListView 封装 实现 下拉刷新/上拉加载更多

    1.PageListView 组件封装 src/components/PageListView/index.js /*** 上拉刷新/下拉加载更多 组件*/ import React, { Compo ...

  2. react-native 自定义 下拉刷新 / 上拉加载更多 组件

    1.封装 Scroller 组件 src/components/Scroller/index.js /*** 下拉刷新/上拉加载更多 组件(Scroller)*/ import React, {Com ...

  3. android SwipeRefreshLayout 增加上拉加载更多

    2019独角兽企业重金招聘Python工程师标准>>> 大家可能有的没有swipeRefreshLayout这个类,简单说一下,这是v4包里面的,19.1版本的时候就有了,但是当时的 ...

  4. Flutter开发之ListView下拉刷新上拉加载更多(35)

    在Flutter开发之ListView组件(21) 文章中,我们了解了ListView组件的基本使用.但是数据比较少,没有涉及分页加载.而实际开发中,下拉刷新和分页加载几乎是所有APP的标配.在iOS ...

  5. 【Flutter】ListView 列表高级功能 ( ScrollController 上拉加载更多 )

    文章目录 一.ScrollController 上拉加载更多 二.ScrollController 使用流程 三.ScrollController 判定滑动到底部 四.完整代码示例 五.相关资源 一. ...

  6. Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向...

    很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性.查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷 ...

  7. ajax 下拉刷新 上拉加载更多,局部刷新iscroll控件的具体使用(下拉刷新,上拉加载更多)...

    标签下,这是调用iscroll的必要条件,否则会出现不能刷新或者不能滑动页面的情况.此外还有商量刷新及下拉刷新的标签,在iscroll中有这两个标签的样式,若不想用默认的样式,也可通过覆盖的方式添加其 ...

  8. webpack+vue+mint-ui 实现上拉加载更多(Loadmore组件)

    因为业务的需要界面需要实现分页的功能,所以我就研究了一下如何利用mint-ui自带的loadmore组件实现上拉加载更多功能. 首先在文件中引入组件 import {Indicator, Loadmo ...

  9. Flutter ListView封装,下拉刷新、上拉加载更多

    Flutter ListView封装,下拉刷新.上拉加载更多 ​ 封装了Flutter的ListView,只要传递请求数据的方法和绘制item的方法进去就可以绘制ListView,同时支持下拉刷新.上 ...

最新文章

  1. 接口测试用例测试模板
  2. 使用CGlib出现java.lang.NoClassDefFoundError: org/objectweb/asm/Type异常
  3. java线程的创建线程_多线程(Thread、线程创建、线程池)
  4. Win10+CUDA10.0.130+cudnn7.4.1+tensorflow1.13.1+anaconda3 5.2.0+GTX1060
  5. python存储大量数据_如何在文件中密集地存储大量数据?
  6. 浏览器“四巨头”首度合作 解决网页适配问题
  7. Leetcode 70.爬楼梯
  8. ArcPad 10 的安装部署
  9. Java汉字转拼音实现方式
  10. 鼠标移入显示图片案例
  11. 论文摘要翻译,多语言纯人工翻译
  12. 【Flutter小记3】Android打开前置或广角摄像头的同时打开闪光灯方案
  13. EasyDemo*CSS尺寸与框模型(六七)
  14. CHERRY 键盘 alt 组合键失灵或开始菜单键失灵
  15. canvas学习日记一
  16. Win7系统下发生一个文件夹,无法删除,解决记录
  17. 设计模式(七)——适配器模式
  18. 网络分层(7层)以及每层的设备和协议
  19. RCNN系列论文学习:RCNN、FastRCNN、FaterRCNN、MaskRCNN(包含IOU、NMS介绍)
  20. mb63.net/ios.html,Document

热门文章

  1. 被迫营业:如何使用向日葵进行远程桌面控制(含MacOS)
  2. TypeError: Object of type 'datetime' is not JSON serializable
  3. 食物链 (种类并查集)
  4. 使用Hyper-V的安卓模拟器-兆懿
  5. 霸气牵手众多手机品牌商,苏宁手机蜜蜂节实力彰显行业影响力
  6. 2022年操作系统行业研究报告
  7. android 个人云存储,个人云储存appv1.3
  8. 动态规划——爬楼梯问题(爬楼梯+最省力爬楼梯)
  9. dlna 交互步骤-转发
  10. 情景模拟面试真题解析