react-app-shell
Version:
react打包脚本和example, 这里的版本请忽略
207 lines (194 loc) • 5.71 kB
JavaScript
import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
import classNames from 'classnames';
import _ from 'lodash';
import styles from './styles.less';
(({ groupStore }) => {
const groupInfo = groupStore.groupInfo;
return {
// 数据
ruleImages: ',,,,' + groupInfo.activityRuleImage || '', // 活动规则图片
productImages: groupInfo.productInfoImage || '' // 产品介绍图片
};
})
export default class GroupTabs extends Component {
constructor(props) {
super(props);
this.leftTabpane = React.createRef();
this.rightTabpane = React.createRef();
this.isMoving = false;
this.sollTime = null;
this.state = {
currentTab: 'product', // 当前选中的tab页面 rule:活动规则 product:产品介绍
imageHeight: null,
fixedMenu: false
};
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll = () => {
if (this.isMoving) return false;
const tabsTop = this.refs.grouptabs.offsetTop - window.pageYOffset;
let { fixedMenu } = this.state;
fixedMenu = tabsTop < 0;
this.setState({
fixedMenu
});
};
/**
* 滚动条运动
*/
move = (iTarget) => {
let iSpeed = 0; // 速度
let iCur = 0; // 当前值
let preiCur = 0; // 上一次iCur的值
const that = this;
this.isMoving = true;
clearInterval(this.sollTime);
this.sollTime = setInterval(function() {
let onOff = true; // 关闭定时器开关
iCur = parseInt(
document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop,
10
); // 获取滚动条值当前值
if (iCur > iTarget) {
iSpeed = Math.floor((iTarget - iCur) / 6);
} else {
iSpeed = Math.ceil((iTarget - iCur) / 6);
}
if (iCur !== iTarget) {
onOff = false;
} else {
onOff = true;
}
if (onOff || preiCur === iCur) {
that.closeMove();
}
preiCur = iCur;
// 运动
const tt = iCur + iSpeed;
window.scrollTo(0, tt);
}, 30);
};
closeMove = () => {
this.isMoving = false;
if (this.sollTime) {
clearInterval(this.sollTime);
}
};
/**
* 切换tabs
*/
handleTabsClick = (key, value) => {
// const imageHeight = value === 'product' ? this.getImagesHeight(this.leftTabpane) : this.getImagesHeight(this.rightTabpane);
let imageHeight = '';
if (value === 'product') {
imageHeight = this.getImagesHeight(this.leftTabpane.current);
} else {
imageHeight = this.getImagesHeight(this.rightTabpane.current);
}
this.setState(
{
[key]: value,
imageHeight: imageHeight
},
() => {
const tabsTop = this.refs.grouptabs.offsetTop;
if (this.state.fixedMenu) {
this.move(tabsTop - 40);
}
}
);
};
/**
* 获取图片高度
*/
getImagesHeight = (refNode) => {
const nodeList = Array.prototype.slice.call(refNode.childNodes);
let height = 0;
nodeList.forEach((node) => {
height += node.height;
});
return `${height}px`;
};
renderRule = () => {
let { ruleImages } = this.props;
ruleImages = _.remove(ruleImages.split(','), (o) => !!o);
return ruleImages.map((item, index) => {
if (item) {
return <img key={`rule${index}`} src={item} alt="活动规则" />;
}
return null;
});
};
renderProduct = () => {
let { productImages } = this.props;
productImages = _.remove(productImages.split(','), (o) => !!o);
return productImages.map((item, index) => {
return <img key={`product${index}`} src={item} alt="产品介绍" />;
});
};
render() {
const { currentTab, imageHeight, fixedMenu } = this.state;
return (
<div className={styles['group-tabs']} ref="grouptabs">
<div
className={classNames(
styles['group-tabs-nav'],
'clearfix',
fixedMenu ? styles['fixedMenu'] : ''
)}
>
<div
onClick={this.handleTabsClick.bind(null, 'currentTab', 'product')}
className={classNames(
styles['group-tabs-tab'],
currentTab === 'product' ? styles['group-tabs-tab-active'] : ''
)}
>
产品介绍
</div>
<div
onClick={this.handleTabsClick.bind(null, 'currentTab', 'rule')}
className={classNames(
styles['group-tabs-tab'],
currentTab === 'rule' ? styles['group-tabs-tab-active'] : ''
)}
>
活动规则
</div>
</div>
<div
className={styles['group-tabs-content']}
style={imageHeight ? { height: imageHeight } : {}}
>
<div
className={classNames(
styles['tabs-content-slide'],
currentTab === 'product' ? '' : styles['group-active']
)}
>
<div className={classNames(styles['group-tabs-tabpane'])} ref={this.leftTabpane}>
{this.renderProduct()}
</div>
<div
className={classNames(
styles['group-tabs-tabpane'],
imageHeight ? '' : styles['tab-product']
)}
ref={this.rightTabpane}
>
{this.renderRule()}
</div>
</div>
</div>
<div className={styles['group-tabs-footer']} />
</div>
);
}
}