H5的虚拟DOM版无限下拉刷新

另一种无限下拉

import {components, config} from "common-utils";
import style from './css/refuse.less';
import {Component} from 'refast';
import Empty from './empty/Empty';
import loadingImg from './imgage/loading.png'
/**
 * data:数据源,
 * total:总数必须大于或等于 data.length,
 * loading:加载状态,
 * current:页码,由组件触发翻页,
 * sensitivity: 灵敏度,越大越灵敏
 * **/
export default class Refuse extends Component {
    constructor(props) {
        super(props);
        let { data = [], current = 1, total = 0, sensitivity = 10 , loading = true} = this.props;
        this.state = {
            loading,
            sensitivity, //灵敏度
            data,
            current,
            total,
        }
    }

    componentWillReceiveProps(nextProps, nextContext) {
        let { data, current, total, loading } = nextProps;
        if( data !== this.state.data ){
            this.setState({
                data,
                loading:false
            }, this.needDom )
        }
        if( current !== this.props.current || total !== this.props.total ) this.setState({ current, total })
        if( loading !== this.props.loading ) this.setState({ loading: nextProps.loading })
    }

    //需要加载
    needDom = () =>{
        let {vListContainer , phantomContent } = this.refs,
            out_height = vListContainer?.clientHeight ?? 0,
            in_height = phantomContent?.clientHeight ?? 0;
            //如果外层Dom高度高于内层Dom那么说明页面还未加载完成
            if( out_height > in_height && !this.state.loading && this.compare() ) this.getData()
    };

    //判断是否有未显示完的数据
    compare = () => { // 还有未显示完的数据,返回true, 兼容 Map 与 数组
        let { data = [], total } = this.state;
        return (data.length || data.size || 0) < total
    };

    //根据页码获取下一页数据
    getData = () => { this.setState({ loading: true },()=>this.props?.addData( this.state?.current + 1 )) }

    //滚动监听
    onScrollList = (e) => {
        let { sensitivity, loading } = this.state;
        let scroll_total_height = this.refs?.phantomContent?.scrollHeight??0; // 总的滚动高度
        let scroll_office = e?.target?.scrollTop??0; // 滚动偏移量,
        let out_height = this.refs?.vListContainer?.clientHeight??0; // 容器高度
        // 滚动偏移量 + 容器高度 + 灵敏度 > 总的滚动高度 且 还有多余数据 且 当前不在加载中 ,触发下一页加载。
        if(scroll_office + out_height + sensitivity > scroll_total_height && this.compare() && !loading) this.getData()
    };

    render() {
        return (
            <div className={style.refuse}>
                <div className={ this.state.loading ? 'vListContainer_loading' : 'vListContainer_loading loading_none' } >
                    <img src={ loadingImg } />
                </div>
                <div className={'vListContainer '}
                     onScroll={(e)=> { e.preventDefault(); this.onScrollList(e) } }
                     ref = {'vListContainer'} >
                    { this.props.children ?  <div className={'phantomContent'} ref = {'phantomContent'}> { this.props.children}  </div> : <Empty /> }
                </div>
            </div>
        );
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值