react--banner

Posted 一朵梨花压海棠 18802686535

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
 

以上是关于react--banner的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数