react--banner

 


import React,{Component,PropTypes} from 'react';
import {circleFunction} from '../main';//绑定this
import {method} from '../common';//通用方法集合
import BannerType from './ButtonType';//左右按钮组件
import Pagination from './Pagination';
class Banner extends Component{
static PropTypes={
menuData:PropTypes.Array,
autoPlay:PropTypes.Bool
};
constructor(props){
super(props);
circleFunction(this,[
'autoPlay','onClickLeft','onClickRight','onTouchStart','onTouchMove','onTouchEnd',
'onMouseDown','onMouseMove','onMouseUp','bind_event'
]);
this.state={
index:0,
indexAfter:null,
aniTime:0.5,
};
this.isRun = false;
this.isMouseEnter = false;
this.timer =null;
this.px = 0;
this.MoveX = 0;
this.startMove = 0;
};
componentDidMount(){
//install width for li
const liWid = this.refs.bannerHorizontal.offsetWidth;
this.setState({liWidth:liWid})
}
componentWillReceiveProps(nextProps){
if('menuData' in nextProps&&this.props.menuData !== nextProps.menuData){
const data1 = method.clone(nextProps.menuData);
const data = nextProps.menuData;
data.unshift(data[data.length-1]);
data.push(data[1]);

this.setState({menuData:data,menuData1:data1},()=>{
if('autoPlay' in nextProps&&nextProps.autoPlay){
this.autoPlay();
}
});
}
}
/*
* 自动轮播功能
* @param menuData 包裹图片的数组
* @param index 图片的索引
* @param isRun 是否开启点击事件
* @param callback 回掉暴露index索引
* */
autoPlay(){
const {index,menuData}= this.state;
const a = new Promise(resolve=>{
if(index>-(menuData.length-2)){
this.setState({index:index-1,aniTime:'0.5'})
}else if(index === - (menuData.length-2)) {
this.setState({index:0,aniTime:'none'},()=>{
setTimeout(()=>{
this.setState({index:-1,aniTime:'0.5'})
},10);
})
}
resolve(index);
clearTimeout(this.timer);
this.timer = setTimeout(() => {
if(this.timer) {
this.autoPlay()
}
}, 2000)
}).then(index=>{
const {callback} = this.props;
if('callback' in this.props){
index === -4 ? callback(0):callback(Math.abs(-index));
}
});

};
//卸载
componentWillUnmount(){
clearTimeout(this.timer);
}
/*
* 左边按钮功能
* @param menuData 包裹图片的数组
* @param index 图片的索引
* @param isRun 是否开启点击事件
* @param callback 回掉暴露index索引
* */
onClickRight(){
const {menuData,index}= this.state;
clearTimeout(this.timer);
if(!this.isRun){
this.isRun = true;
if(index>-(menuData.length-2)){
this.setState({index:index-1,aniTime:'0.5'})
}else if(index === - (menuData.length-2)) {
this.setState({index:0,aniTime:'none'},()=>{
setTimeout(()=>{this.setState({index:-1,aniTime:'0.5'})},10);
})
}
const {callback} = this.props;
if('callback' in this.props){
index === -4 ? callback(0):callback(Math.abs(-index));
}
setTimeout(()=>this.isRun = false,500)
}
}
/*
* 右边按钮功能
* @param menuData 包裹图片的数组
* @param index 图片的索引
* @param isRun 是否开启点击事件
* @param callback 回掉暴露index索引
* */
onClickLeft(){
const {menuData,index}= this.state;
clearTimeout(this.timer);
if(!this.isRun){
this.isRun = true;
if(index ===-1){
this.setState({index:(-(menuData.length-1)),aniTime:'none'},()=>{
setTimeout(()=>{this.setState({index:-(menuData.length-2),aniTime:'0.5'})},10);
})
}else {
this.setState({index:index+1,aniTime:'0.5'})
}
const {callback} = this.props;
if('callback' in this.props){
index === -1 ? callback(menuData.length-3):callback(Math.abs(index+2));
}
setTimeout(()=>this.isRun = false,500)
}
}
//Pagination
callbackPag=(data)=>{
clearTimeout(this.timer);
const {callback} = this.props;
if('callback' in this.props){
callback(Math.abs(data));
}
this.setState({index:-(data+1)})
};
//map img ·
mapList=(data)=>{
const {liWidth} = this.state;
return data.map((item,i)=>{
return <li style={{width:`${liWidth}px`}} key={i}>
<img alt={item.name} src={`./img/${item.url}`}/>
</li>
});
};
onTouchStart=(e)=>{
e.preventDefault();
clearTimeout(this.timer);
this.px = e.nativeEvent.changedTouches[0].pageX;
};
onTouchMove=(e)=>{
e.preventDefault();
clearTimeout(this.timer);
if(!this.isRun){
this.MoveX = e.nativeEvent.changedTouches[0].pageX - this.px;
this.refs.ul.style = `-webkit-transform:translateX(${this.state.liWidth*this.state.index+this.MoveX}px)`
}
};
onTouchEnd(e){
e.preventDefault();
this.bind_event();
};
onMouseDown(e){
e.preventDefault();
clearTimeout(this.timer);
this.px = e.nativeEvent.clientX;
this.isMouseEnter = true;
};
onMouseMove(e){
e.preventDefault();
//clearTimeout(this.timer);
if(this.isMouseEnter){
this.MoveX = e.nativeEvent.clientX - this.px;
this.refs.ul.style = `-webkit-transform:translateX(${this.state.liWidth*this.state.index+this.MoveX}px)`
}
};
onMouseUp(e){
e.preventDefault();
this.isMouseEnter = false;
this.bind_event();
};
/*
* 绑定移动事件功能
* @param menuData 包裹图片的数组
* @param index 图片的索引
* @param callback 回掉暴露index索引
* */
bind_event(){
const {menuData,index}= this.state;
const {callback} = this.props;
this.refs.ul.style =`transition:0.5s`;
if(this.MoveX<0&&this.MoveX>-100||this.MoveX>0&&this.MoveX<100){
this.refs.ul.style = `-webkit-transform:translateX(${this.state.liWidth*this.state.index}px)`
}else{
if(this.MoveX<-100){
if(index === - (menuData.length-2)) {
this.setState({index:- (menuData.length-1),aniTime:'0.5'},()=>{
setTimeout(()=>{
this.setState({index:-1,aniTime:'none'})
},450);
})
}else{
this.setState({index:index-1,aniTime:'0.5'})
}
if('callback' in this.props){
callback(Math.abs(index));
}
}else if(this.MoveX>100){
if(index ===-1){
this.setState({index:0,aniTime:'0.5'},()=>{
setTimeout(()=>{
this.setState({index:-(menuData.length-2),aniTime:'none'})
},450);
})
}else {
this.setState({index:index+1,aniTime:'0.5'})
}
if('callback' in this.props){
index === -1 ? callback(menuData.length-3):callback(Math.abs(index+2));
}
}
}
}
render(){
const {index,menuData,liWidth,aniTime,menuData1}=this.state;
const {showButton,showPagination} = this.props;
const ani = {
WebkitTransform:`translateX(${liWidth*index}px)`,
transition:`${aniTime}s`,
};
return (
<div
ref="bannerHorizontal"
className={`bannerHorizontal ${this.props.className}`}
style={{...this.props.style}}
>
<ul
onTouchStart={this.onTouchStart}
onTouchMove={this.onTouchMove}
onTouchEnd={this.onTouchEnd}
onMouseDown={this.onMouseDown}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
ref="ul" style={{transition:'0.5s',...ani}}
className="imgWap clearfix">
{!!menuData&&this.mapList(menuData)}
</ul>
{this.props.children}
{showButton&&<BannerType {...this}/>}
{showPagination&&<Pagination index={-(index+1)} data={menuData1} {...this}/>}
</div>
)
}
}
export default Banner;

//按钮组件
class BannerType extends Component{
constructor(props){
super(props);
circleFunction(this,['onClickLeft','onClickRight']);
};
//
onClickLeft(){
this.props.onClickLeft();
}
onClickRight(){
this.props.onClickRight();
}
render(){
return (<div className="bannerType">
<div onClick={this.onClickLeft} className="button buttonLeft"><Icon type="left"/></div>
<div onClick={this.onClickRight} className="button buttonRight"><Icon type="right"/></div>
</div>)
}
}
export default BannerType;

//type 组件
class Pagination extends Component{
static PropTypes={
index:PropTypes.number
};
constructor(props){
super(props);
circleFunction(this,['callbackPag']);
};
componentWillReceiveProps(nextProps){
if('index' in nextProps){
this.setState({index:nextProps.index})
}
}
//call
callbackPag(i){
this.props.callbackPag(i)
}
mapLiToUl=(data)=>{
let {index} = this.state;
if(index ===-1){
index = data.length -1;
}else if(index ===data.length){
index = 0;
}
return data.map((item,i)=>{
if(index === i){
return <li onClick={()=>this.callbackPag(i)} className="active_p" key={i}></li>
}
return <li onClick={()=>this.callbackPag(i)} key={i}></li>
});
};
render(){
const {data} = this.props;
return (<div className="bannerPagination">
<ul className="clearfix">
{!!data&&data.length>0&&this.mapLiToUl(data)}
</ul>
</div>)
}
}
export default Pagination;
 

转载于:https://www.cnblogs.com/leijuan/p/7633065.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值