当前位置: 首页 > 工具软件 > BetterScroll > 使用案例 >

React+BetterScroll简单应用

封锐藻
2023-12-01
npm install @better-scroll/core --save

// or

yarn add @better-scroll/core

index

import React, { useRef, useEffect, useState } from 'react'
import styles from './style.less'
import { BS, debounce } from './utils/index'
const index = () =>
{
    const [rollingArea, setRollingArea] = useState(0)  // 滚动位置
    const [bsContainer, setBsContainer] = useState(null)  // 保存 BS
    const [scrollName, setScrollTitle] = useState("正在加载中")
    const scrollRef = useRef()
    useEffect(() =>
    {  // 发送数据请求 设置订阅/启动定时器 手动更改 DOM 等 ~  // scrolled 记录滚动  pullUp 记录上拉
        BS('wrapper', setBsContainer, { payload: { params: null, callback: { scrolled, pullUp } } })  // 传递三个参数 DOM节点、用于保存 BS 对象、 payload:传递一个 params 暂时没作用 callback 用于 接收传递过来的值
        window.addEventListener('resize', debounce(function ()
        {
            console.log('屏幕调整大小');
        }, 1000))
        // BS(scrollRef.current)  // 发送 Ref 也可以发送 DOM 节点  BS('wrapper')
        return () =>
        {  // 组件卸载之前 做一些收尾工作 比如清楚定时器/取消订阅 等 ~
        }
    }, [])  // 检测数组内变量 如果为空 则监控全局
    // 滚动事件

    const scrolled = debounce((roll, bs) =>
    {  // roll 滚动位置 bs BScroll 对象
        const { x, y } = roll  // x y 轴的距离
        // bs && bs.refresh()  //  按钮因为没有写到 content 也就不会影响到滚动的高度 所以也就不需要加 refresh
        setRollingArea(y)  // 保存 Y 轴位置
    }, 100)  // 展示的慢 因为加了防抖函数

    const pullUp = (title) =>
    {
        setScrollTitle(title)
    }
    const btnClick = debounce(() =>
    {
        bsContainer.scrollTo(200, -1000, 2000)  // X轴 Y轴 时间 
    }, 1000)
    const btnBack = () =>
    {
        bsContainer.scrollTo(750, 0, 2000)  // X轴 Y轴 时间 
    }
    console.log(scrollName, 'scrollName');
    return (
        <div className={styles.container}>
            {rollingArea <= -1000 ? (<button onClick={btnBack} className={styles.btn} >点击返回顶部</button>) : null}

            <div id='wrapper' ref={scrollRef} className={styles.wrapper}>

                <div className={styles.content}>
                    <div className={styles.dd}>{scrollName}</div>
                    <button onClick={btnClick}>按钮点击</button>
                    <div>1</div>
                    <div>2</div>
                    <div>3</div>
                    <div>4</div>
                    <div>5</div>
                    <div>6</div>
                    <div>7</div>
                    <div>8</div>
                    <div>9</div>
                    <div>10</div>
                    <div>11</div>
                    <div>12</div>
                    <div>13</div>
                    <div>14</div>
                    <div>15</div>
                    <div>16</div>
                    <div>17</div>
                    <div>18</div>
                    <div>19</div>
                    <div>20</div>
                    <div>21</div>
                    <div>22</div>
                    <div>23</div>
                    <div>24</div>
                    <div>25</div>
                    <div>26</div>
                    <div>27</div>
                    <div>28</div>
                    <div>29</div>
                    <div>30</div>
                    <div>31</div>
                    <div>32</div>
                    <div>33</div>
                    <div>34</div>
                    <div>35</div>
                    <div>36</div>
                    <div>37</div>
                    <div>38</div>
                    <div>39</div>
                    <div>40</div>
                    <div>41</div>
                    <div>42</div>
                    <div>43</div>
                    <div>44</div>
                    <div>45</div>
                    <div>46</div>
                    <div>47</div>
                    <div>48</div>
                    <div>49</div>
                    <div>50</div>
                    <div>51</div>
                    <div>52</div>
                    <div>53</div>
                    <div>54</div>
                    <div>55</div>
                    <div>56</div>
                    <div>57</div>
                    <div>58</div>
                    <div>59</div>
                    <div>60</div>
                    <div>61</div>
                    <div>62</div>
                    <div>63</div>
                    <div>64</div>
                    <div>65</div>
                    <div>66</div>
                    <div>67</div>
                    <div>68</div>
                    <div>69</div>
                    <div>70</div>
                    <div>71</div>
                    <div>72</div>
                    <div>73</div>
                    <div>74</div>
                    <div>75</div>
                    <div>76</div>
                    <div>77</div>
                    <div>78</div>
                    <div>79</div>
                    <div>80</div>
                    <div>81</div>
                    <div>82</div>
                    <div>83</div>
                    <div>84</div>
                    <div>85</div>
                    <div>86</div>
                    <div>87</div>
                    <div>88</div>
                    <div>89</div>
                    <div>90</div>
                    <div>91</div>
                    <div>92</div>
                    <div>93</div>
                    <div>94</div>
                    <div>95</div>
                    <div>96</div>
                    <div>97</div>
                    <div>98</div>
                    <div>99</div>
                    <div>100</div>
                </div>
            </div>
        </div >
    )
}

export default index

utils



import BScroll from '@better-scroll/core'  // BScroll 核心
import MouseWheel from '@better-scroll/mouse-wheel'  // 引入滚轮
import PullDown from '@better-scroll/pull-down'  // 上拉

// import Scrollbar from '@better-scroll/scroll-bar'
// BScroll.use(Scrollbar)


BScroll.use(MouseWheel)  // 下载滚轮插件
BScroll.use(PullDown)  // 下载上拉 
export const BS = (wrapper, setBsContainer = false, action = false,) =>
{
    const { payload } = action
    if (wrapper)
    {
        if (typeof wrapper === 'string')
        {
            let wrapperRef = document.querySelector('#' + wrapper)
            deploy(wrapperRef ? wrapperRef : null, setBsContainer ? setBsContainer : null, payload ? payload.callback : null)
        } else
        {
            deploy(wrapper ? wrapper : null, setBsContainer ? setBsContainer : null, payload ? payload.callback : null)
        }
    }
}

const deploy = (wrapper, setBsContainer, callback) =>
{
    console.log(setBsContainer, 'setBsContainer');
    console.log(callback, 'callback');
    let bs = new BScroll(wrapper, {
        probeType: 3,  // 默认0 不侦测 0和1 都不侦测  2:在手指滚动的过程中侦测 手指离开后的惯性滚动过程中不侦测 3:只要是滚动 都进行侦测
        click: true,  // 可以点击  用法:要覆盖本机滚动,BetterScroll必须禁止某些默认浏览器行为,例如鼠标单击。如果您希望您的应用程序响应click事件,则必须将该选项显式设置为true。然后BetterScroll将向其_constructed调度事件添加一个私有属性,该属性的值为true。
        pullDownRefresh: true,  // 向上拉 可以上拉 请求数据 加载更多
        mouseWheel: true,  // 鼠标滚轮
    })
    // 监听事件 滚动 https://better-scroll.github.io/docs/en-US/

    if (setBsContainer) setBsContainer(bs)  // 用于保存 bs 对象

    bs.on('scroll', position =>
    {
        if (callback)
        {
            const { scrolled } = callback
            scrolled(position, bs) // 发送两个参数 position 位置  bs 对象
        }
        // 默认情况下 BScroll 是不可以实时监听滚动位置
        // console.log(position); // 实时滚动的位置
    })
    bs.on('pullingDown', () =>
    {
        // 触发时机:在一次上拉加载的动作后 这个时机一般用来去后端请求数据
        // bs.finishPullUp()
        // 注意 只能回调一次
        console.log('上拉加载更多');
        // 先去发送网络请求 请求更多页的数据

        // 等数据强求完成 并将数据展示出来
        setTimeout(() =>
        {
            bs.finishPullDown()
            if (callback)
            {
                const { pullUp } = callback
                pullUp('猪猪你看到了吗')
            }
            // bs.refresh()
            // bs.finishPullUp()   // 可以再次执行
        }, 2000)  // 两秒拉一次
    })

    // btn.addEventListener('click', function ()
    // {
    //     console.log('---');
    // })
}





// export const DS = (data, HorizontalAxis) =>
// {
//     console.log(HorizontalAxis);
//     let wrapper = document.querySelector('#' + data)
//     if (wrapper)
//     {
//         new BScroll(wrapper, {
//             probeType: 0,
//             click: true,
//             pullUpLoad: true,
//             mouseWheel: true,
//             scrollX: true,
//             scrollY: false,
//             scrollbar: {
//                 customElements: [HorizontalAxis.current],
//                 fade: true,
//                 interactive: true,
//                 // scrollbarTrackClickable: true
//             }
//         })
//     }

// }



// 防抖函数
export const debounce = (func, delay) =>
{
    let timer = null;
    return function (...args)
    {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() =>
        {
            func.apply(this, args);
        }, delay);
    };
}

css

.container {
  position: relative;
  width: 100%;
  height: 100%;

  .wrapper {
    position: relative;
    margin: 0 auto;
    width: 800px;
    height: 400px;
    background-color: pink;
    overflow: hidden;


  }
}

.dd {
  position: absolute;
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  transform: translateY(-100%) translateZ(0);
  text-align: center;
  color: #999;
}

.btn {
  position: fixed;
  top: 100px;
  right: 100px;
}

 类似资料: