移动端刷新组件XtnScroll--ReactJS实现

XtnScroll 组件,先看一下效果图

下拉的效果
这里写图片描述
上拉的效果
这里写图片描述

  • 以前都是用Vue–XtnScroll、Angular4–XtnScroll来实现的刷新组件今天说说React怎么实现。其实这三种框架里用到的方法都是一样的,只是每个里面都有自己的语法特性不一样,所以实现起来大同小意了。

创建组件步骤

目录结构如下图所示

这里写图片描述

  • scss 样式文件
  • svg 加载动画
  • XtnScroll.js真正的文件

XtnScroll.js文件

import React, { Component, PropTypes } from 'react';
import { Utility } from 'components';
const styles = require('./scss/XtnScroll.scss');
/*** {....}}*   onNextData={()=>{....}}* />*/
export default class XtnScroll extends Component {}
属性
   static propTypes = {children: PropTypes.any,                   // 子项Percentage: PropTypes.number,              // 百分比RefreshComplete: PropTypes.bool,           // 刷新完成NextDataComplete: PropTypes.bool,          // 加载更多数据完成onRefresh: PropTypes.func,                 // 刷新操作onNextData: PropTypes.func,                // 更多数据}
render方法
  • 里面三个主要方法 onTouchStart、onTouchEnd、onTouchMove。分别对应的三个事件__HandlerStart、__HandlerEnd、__HandlerMove。
  render() {const { RefreshComplete, NextDataComplete } = this.props;return (<div ref="divXtnScroll" className={styles.refreshCss} style={this.__GetStyle()}onTouchStart={this.__HandlerStart.bind(this)}onTouchEnd={this.__HandlerEnd.bind(this)}onTouchMove={this.__HandlerMove.bind(this)}>{!LoadType ?<div className={styles.refreshAnimation + ' ' + (RefreshComplete ? styles.hideRefresh : styles.showRefresh)}><div>div>div>:<div ref="divOtherAni" className={styles.otherAni}><div><div ref="divLoading">div><div ref="divOtherAniDesc">div>div>div>}<div className={styles.content} ref="divContent">{this.props.children}div><div
          className={styles.loadingMoreDataAnimation + ' ' + (NextDataComplete ? styles.hideLoadMore : styles.showLoadMore)}><div className={styles.spinner}><div className={styles.bounce1}>div><div className={styles.bounce2}>div><div className={styles.bounce3}>div>div>div>div>);}
__HandlerStart 开始移动方法
  • 这主要是记录当前的位置信息
  /*** 开始移动* * @param {any} event* * @memberOf Refresh*/__HandlerStart(event) {const { clientX, clientY } = event.touches[0];this.state.startX = clientX;this.state.startY = clientY;}
__HandlerMove 开始移动操作。
  __HandlerMove(event) {this.__ProcessAniStart(event);// android 版本小 5的话,是没有 end事件的。只有start,和move事件。const { version } = Utility.$androidVersion() || {};if (!version) {return;}if (version > '5.0') {return;}this.__HandlerEnd(event);}
  • __ProcessAniStart 主要是用于判断向下拉显示相应的字信息。
  __ProcessAniStart(event) {const { LoadType, RefreshComplete, NextDataComplete } = this.props;if (!LoadType || !RefreshComplete || !NextDataComplete) {return;}const { clientY } = event.changedTouches[0];this.state.moveY = clientY;const { startY } = this.state;const abs = clientY - startY;const { divContent, divOtherAni, divOtherAniDesc, divLoading } = this.refs;const __MaxValue = 200;if (abs > 0) {divLoading.classList.remove(styles.loading);divOtherAni.classList.remove(styles.hide);if (abs <= __MaxValue) {const __3d = 'translate3d(0px, ' + abs + 'px, 0px)';divContent.style.transform = __3d;divContent.style.webkitTransform = __3d;divOtherAni.style.transform = __3d;divOtherAni.style.webkitTransform = __3d;divOtherAniDesc.innerHTML = '下拉刷新';}if (abs > __MaxValue) {divOtherAniDesc.innerHTML = '释放立即更新';}}}
__HandlerEnd 移动结束事件
  • 移动结束这个时候要判断移动的方向,向上或下拉,还是向左右滑动。判断好相应的方法后,通知父级组件,调用相应的方法了。
/*** 移动结束* * @param {any} event* @returns* * @memberOf Refresh*/__HandlerEnd(event) {this.__ProcessSlideEnd();const { RefreshComplete, NextDataComplete } = this.props;if (!RefreshComplete || !NextDataComplete) {return;}const { startX, startY } = this.state;const { clientY, clientX } = event.changedTouches[0];const xes = clientX - startX;const yes = clientY - startY;const absXes = Math.abs(xes);const absYes = Math.abs(yes);if (absXes < 10 && absYes < 10) {return;}this.__ProcessAniEnd();if (xes > 0) { // 右if (yes > 0) {// 向下// 判断主向if (absXes > absYes) {// 向右。this.__HandlerSlideRight();} else {// 向下。this.__HandlerRefresh();}} else {// 向上if (absXes > absYes) {// 向右。this.__HandlerSlideRight();} else {// 向上。this.__HandlerNextData();}}} else {// 左边if (yes > 0) {// 向下if (absXes > absYes) {// 向左。this.__HandlerSlideLeft();} else {// 向下。this.__HandlerRefresh();}} else {// 向上if (absXes > absYes) {this.__HandlerSlideLeft();} else {this.__HandlerNextData();}}}}
  • __HandlerNextData 事件,判断是否要通知父级组件调用获取下一页数据的接口。
/*** 下一页数据* * @returns* * @memberOf Refresh*/__HandlerNextData() {const { onNextData, NextDataComplete } = this.props;if (!Utility.isFunction(onNextData) || NextDataComplete === false) {return;}const Percentage = this.props.Percentage || 1;const __bodyScrollTop = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset;const __bodyScrollHeight = document.body.scrollHeight || document.documentElement.scrollHeight;const __differValue = ((__bodyScrollHeight - __bodyScrollTop - screen.height) / __bodyScrollHeight) * 100;if (__differValue > (Percentage < 2 ? 2 : Percentage)) {return;}onNextData();}

. __HandlerRefresh 判断是否要告诉父级组件要刷新数据操作

  /*** 刷新* * @returns* * @memberOf Refresh*/__HandlerRefresh() {const divXtnScroll = this.refs.divXtnScroll;const body = document.body;const __differenceValue = body.scrollHeight - divXtnScroll.scrollHeight;const __bodyScrollTop = body.scrollTop;if (__bodyScrollTop > __differenceValue) {return;}const { onRefresh, RefreshComplete } = this.props;if (!Utility.isFunction(onRefresh) || RefreshComplete === false) {return;}onRefresh();}

核心代码基本上就这些了,想看完整的代码,可以到 Github上查看。也可以将项目下载下来,然后看运行效果了。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部