支持滑动 左右移动 是否需要组件按钮 分页 回掉
import React,{Component,PropTypes} from ‘react‘;import {circleFunction} from ‘../main‘;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‘,‘onMouseLeave‘,‘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){ 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(); } }); } } //autoPlay 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); } //prev button 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) } } //next button 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)}) }; //leave to trigger onMouseLeave(){ this.timer = setTimeout(() => { if(this.timer&&this.props.autoPlay) { this.autoPlay() } }, 5000) }; //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(); }; 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} onMouseLeave={this.onMouseLeave} 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;
时间: 2024-08-04 05:51:30