react+tsx中使用better-scroll详解
目录
- 配置与初始化
- 实践
首先,你要知道为什么可以滚动,原理很简单,父容器的高度比子元素的小即可。
在这之前,我们先来看一下浏览器的滚动原理: 浏览器的滚动条大家都会遇到,当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是当我们的视口展示不下内容的时候,会通过滚动条的方式让用户滚动屏幕看到剩余的内容。
第二,你需要滚动的元素应该是父元素下的第一个子元素。
这里要注意的是,BetterScroll 默认处理容器(wrapper)的第一个子元素(content)的滚动,其它的元素都会被忽略。
第三,为什么我满足了上面两条,为什么还是不能滚动?可能你的content用了异步的数据,better-scroll实例化之后content的高度还是初始时的高度,这当然无法滚动,解决方法是获取到了异步的数据之后使用
refresh()
更新,或是使用插件@better-scroll/observe-dom
来自动更新高度, 或者observeDOM: true,配置与初始化
这里我使用了
better-scroll
官方提供的几个插件,ObserveDOM
、MouseWheel
、ScrollBar
、PullDown
和Pullup
。大致的结构
import BScroll from '@better-scroll/core'import { BScrollConstructor } from '@better-scroll/core/dist/types/BScroll'import ObserveDOM from '@better-scroll/observe-dom'import MouseWheel from '@better-scroll/mouse-wheel'import ScrollBar from '@better-scroll/scroll-bar'import PullDown from '@better-scroll/pull-down'import Pullup from '@better-scroll/pull-up' export interface ScrollProps {wrapHeight: string; prop?: any; onPullup?: Function; onPulldown?: Function; } const Scroll: React.FC = ({wrapHeight,prop,onPullup,onPulldown,children,}) => {BScroll.use(ObserveDOM)BScroll.use(MouseWheel)BScroll.use(ScrollBar)BScroll.use(PullDown)BScroll.use(Pullup) // ... return ({children})} export default Scroll
ok,准备工作完成,接下来准备
better-scroll
的实例化BetterScroll 提供了一个类,实例化的第一个参数是一个原生的 DOM 对象。当然,如果传递的是一个字符串,BetterScroll 内部会尝试调用 querySelector 去获取这个 DOM 对象。
//外层的wrap实例const wrapRef = useRef(null) //记录Better-scroll是否实例化,为后续挂载下拉刷新和上拉加载做准备const initRef = useRef(false) //存储better-scroll的实例const [scrollObj, setscrollObj] = useState() //better-scroll的配置参数const initBScroll = () => {setscrollObj(new BScroll(wrapRef.current as HTMLDivElement, {//probeType 为 3,任何时候都派发 scroll 事件,包括调用 scrollTo 或者触发 momentum 滚动动画probetype: 3,//可以使用原生的点击click: true,//检测dom变化observeDOM: true,//鼠标滚轮设置mouseWheel: {speed: 20,invert: false,easeTime: 300},//显示滚动条scrollY: true,scrollbar: true,//过度动画, 在下载更多的时候滚动条会有个过度动画useTransition: true,//下拉刷新pullDownRefresh: {threshold: 70,stop: 0},//上拉加载更多pullUpLoad: {threshold: 90,stop: 10}}))}
接着是在组件挂载阶段时,将better-scroll进行实例化,以及为其添加下拉和上拉监听函数
//对象初始化useEffect(() => {initBScroll()return () => {//组件卸载时记得将其销毁scrollObj?.destroy()}}, []) //下拉刷新const pulldown = async () => {onPulldown && (await onPulldown())setTimeout(() => {//记得使用finishPullDown,不然你只能下拉一次scrollObj?.finishPullDown()//下拉之后你的content会发生变化,如果不使用refresh,你需要滑动一下才能刷新content的高度scrollObj?.refresh()}, 500)} //上拉加载const pullup = async () => {onPullup && (await onPullup())setTimeout(() => {scrollObj?.finishPullUp()scrollObj?.refresh()}, 500)} //对象事件挂载useEffect(() => {if (initRef.current === true) {//下拉刷新//每次更新都需要先把之前的pullingDown事件清除,不然会累加scrollObj?.off("pullingDown"); scrollObj?.once("pullingDown", pulldown); //上拉加载//每次更新都需要先把之前的pullingUp事件清除,不然会累加scrollObj?.off("pullingUp"); scrollObj?.once("pullingUp", pullup); } else {initRef.current = true; }//为什么监听prop是因为这边监听不到外面的state变化//handlePullUp的[...state, ...res.data]中的state会中始终为一开始的[]}, [prop]);
实践
import React, { CSSProperties, useEffect, useState, useCallback } from "react"; import Scroll from "./scroll"; import axios, { Method } from "axios"; export interface TestProps {} interface ResponseType {code: number; data: any; } const Test: React.FC= () => {const style: CSSProperties = {width: "500px",}; const request = (url: string, method: Method): Promise => {return new Promise((resolve, reject) => {const options = {url,method,}; axios(options).then((res) => {const data = https://www.it610.com/article/res.data as ResponseType; resolve(data); }).catch((err) => reject(err)); }); }; const getData = https://www.it610.com/article/() => request("/api/datasource", "GET"); const getMore = () => request("/api/abc", "GET"); const [state, setstate] = useState([]); // 一开始拉取数据useEffect(() => {(async function () {const res = await getData(); console.log(res); res.code === 0 && setstate(res.data); })(); }, []); const handlePullUp = useCallback(async () => {const res = await getMore(); res.code === 0 && setstate(state.concat(res.data)); }, [state]); async function handlePullDown() {const res = await getData(); res.code === 0 && setstate(res.data); } return ({state.map((item, idx) =>idx % 2 === 0 ? ({item}) : ({item}))}); }; export default Test;
【react+tsx中使用better-scroll详解】到此这篇关于react+tsx中使用better-scroll的文章就介绍到这了,更多相关react使用better-scroll内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 房地产|【房地产行业周报】融创中国回应债权人清盘;富力地产亏损出售北京富力万达嘉华酒店;郑州发布“大干30天,确保停工楼盘全面复工”专项行动
- SCI|FigDraw 19. SCI文章中绘图之坡度图(Slope Chart)
- SCI|FigDraw 20. SCI文章中绘图之马赛克图 (mosaic)
- java|Java 中台技术盘点,这些技术你了解还远远不够
- 数学建模用python好吗_数模算法(如何使用python完成数学建模常见算法)
- uniapp|uniapp(微信小程序使用高德地图进行坐标反解析获取详细地址)
- Uni-app|uniapp 小程序中使用逆地址解析 获取当前详细地址
- UE4自动打包工具编写
- 单片机|猿创征文 | 实验一 单片机keil51软件使用及IO控制
- 投稿|最挤中秋档:12部新片,看了个寂寞