/** * @componentName Pull * @describe -- 提供上下拉动加载等功能 * @ues 列表组件 * @author liulei * @since 5.28 开发完成 * */ import Taro, { Component } from '@tarojs/taro'; import { View, Text, ScrollView } from '@tarojs/components'; import { AtActivityIndicator } from 'taro-ui'; import '../../styles/components/pull.scss'; interface IProps { /* 滚动条到底部回调方法 */ onLower?:() => void /* 滚动条到顶部回调方法 */ onUpper?:() => void /* 上拉回调方法 */ onPullUp?:() => void /* 下拉回调方法 */ onPullDown?:() => void /* 是否使用顶部自定义动画 */ headerCustom?: boolean /* 顶部自定义动画 */ renderHeader?: JSX.Element /* 是否使用底部自定义动画 */ footerCustom?: boolean /* 底部自定义动画 */ renderFooter?: JSX.Element /* 指定容器高度 */ warpperHeight?: number } interface IState { scrollY:boolean, dargStyle: object, downDragStyle: object, upDragStyle: object, start_p: { clientX: number, clientY: number, }, dargState: number, downText: string, pullText: string, scrollTop:number, } class TctPull extends Component { componentWillMount() { } constructor(props) { super(props); this.state = { dargStyle: {// 下拉框的样式 top: `${0}rpx`, }, downDragStyle: {// 下拉图标的样式 height: `${0}rpx`, }, downText: '下拉刷新', upDragStyle: {// 上拉图标样式 height: `${0}rpx`, }, pullText: '上拉加载更多', start_p: { clientX: 0, clientY: 0, }, scrollY: true, dargState: 0, // 刷新状态 0不做操作 1刷新 -1加载更多 scrollTop: 0, }; } pullUp() { // 上拉 if (this.props.onPullUp) this.props.onPullUp(); } pullDown() { // 下拉 if (this.props.onPullDown) this.props.onPullDown(); } ScrollToLower() { // 滚动到底部事件 if (this.props.onLower) { this.props.onLower(); } } ScrollToUpper() { // 滚动到顶部事件 if (this.props.onUpper) { this.props.onUpper(); } } reduction() { // 还原初始设置 const time = 0.5; this.setState({ upDragStyle: {// 上拉图标样式 height: `${0}rpx`, transition: `all ${time}s`, }, dargState: 0, dargStyle: { top: `${0}rpx`, transition: `all ${time}s`, }, downDragStyle: { height: `${0}rpx`, transition: `all ${time}s`, }, scrollY: true, }); setTimeout(() => { this.setState({ dargStyle: { top: `${0}rpx`, }, upDragStyle: {// 上拉图标样式 height: `${0}rpx`, }, pullText: '上拉加载更多', downText: '下拉刷新', }); }, time * 1000); } touchStart(e) { this.setState({ start_p: e.touches[0], }); } touchmove(e) { const move_p = e.touches[0]; const // 移动时的位置 deviationX = 0.30; const // 左右偏移量(超过这个偏移量不执行下拉操作) deviationY = 70; const // 拉动长度(低于这个值的时候不执行) maxY = 100;// 拉动的最大高度 const { onPullDown, onPullUp } = this.props; const start_x = this.state.start_p.clientX; const start_y = this.state.start_p.clientY; const move_x = move_p.clientX; const move_y = move_p.clientY; // 得到偏移数值 const dev = Math.abs(move_x - start_x) / Math.abs(move_y - start_y); if (dev < deviationX) { // 当偏移数值大于设置的偏移数值时则不执行操作 let pY = Math.abs(move_y - start_y) / 3.5;// 拖动倍率(使拖动的时候有粘滞的感觉--试了很多次 这个倍率刚好) if (onPullDown && (move_y - start_y > 0)) { // 下拉操作 if (pY >= deviationY) { this.setState({ dargState: 1, downText: '释放刷新' }); } else { this.setState({ dargState: 0, downText: '下拉刷新' }); } if (pY >= maxY) { pY = maxY; } this.setState({ dargStyle: { top: `${pY}rpx`, }, downDragStyle: { height: `${pY}rpx`, }, scrollY: false, // 拖动的时候禁用 }); } if (onPullUp && (start_y - move_y > 0)) { // 上拉操作 if (pY >= deviationY) { this.setState({ dargState: -1, pullText: '释放加载更多' }); } else { this.setState({ dargState: 0, pullText: '上拉加载更多' }); } if (pY >= maxY) { pY = maxY; } this.setState({ dargStyle: { top: `${-pY}rpx`, }, upDragStyle: { height: `${pY}rpx`, }, scrollY: false, // 拖动的时候禁用 }); } } } scrollTop() { this.setState({ scrollTop: 0 }); } touchEnd() { if (this.state.dargState === 1) { this.pullDown(); } else if (this.state.dargState === -1) { this.pullUp(); } this.reduction(); } render() { const { dargStyle, downDragStyle, upDragStyle, scrollTop } = this.state; const warpperHeight = this.props.warpperHeight ? this.props.warpperHeight : Taro.getSystemInfoSync().windowHeight; const { headerCustom, footerCustom } = this.props; return ( {headerCustom ? this.props.renderHeader : {this.state.downText} } {this.props.children} { footerCustom ? this.props.renderFooter : {this.state.pullText} } ); } } export default TctPull;