react.js的基本思想,是通过改变state或props的值,重新渲染用户界面(不用操作DOM)。截图GIF效果如下(只截取了三页效果):
1.文件列表:
2.组件功能说明:
1.可控制滚动方向(上下左右)
2.可控制轮播图片的宽高
3.可控制轮播图片的数量
4.可控制轮播图片停留时间
5.可控制轮播的风格
6.轮播的基本功能(dots,左右按钮,鼠标滑入滑出的暂停与播放,无缝)
3.组件使用说明:
用户修改json中的数据即可使用,
- imgArray ---------------------------- 数组类型,放置轮播图片的地址(必填)
- linkArray ---------------------------- 数组类型,放置点击图片访问的地址(必填)
- lunboObject ------------------------ json类型,放置一些轮播图的基本设置(必填)
- interval ---------------------------- number类型,设置图片停留时间
- direction -------------------------- string类型,设置运动的方向
- number --------------------------- number类型,设置图片数量(必填)
- boxStyle -------------------------- string类型,设置某些地方的样式
- imgWidth ------------------------- number类型,设置图片宽度(必填)
- imgHeight ------------------------ number类型,设置图片高度(必填)
4.组件内容:
1.data.json
"imgArray": [
"../src/pages/lunbo/img/1.jpg",
"../src/pages/lunbo/img/2.jpg",
"../src/pages/lunbo/img/3.jpg",
"../src/pages/lunbo/img/4.jpg",
"../src/pages/lunbo/img/5.jpg",
"../src/pages/lunbo/img/6.jpg",
"../src/pages/lunbo/img/7.jpg"
],
"linkArray": [
"http://bj.ganji.com",
"http://bj.ganji.com",
"http://bj.ganji.com",
"http://bj.ganji.com",
"http://bj.ganji.com",
"http://bj.ganji.com",
"http://bj.ganji.com"
],
"lunboObject": {
"interval": 1000,
"direction": "right",
"number": 7,
"boxStyle": "content",
"imgWidth": 550,
"imgHeight": 350
}
}
2.lunbo.jsx
var style = require('./lunbo.less');
var ReactDOM = require('react-dom');
var React = require('react');
var data = require('./data.json');
var LunBoControl = React.createClass({
/*对出入的props进行验证*/
propsTypes : {
defaultActiveIndex:React.PropTypes.number,
interval:React.PropTypes.number,
direction:React.PropTypes.oneOf['right','left','top','bottom'],
number:React.PropTypes.number,
boxStyle:React.PropTypes.string,
imgWidth:React.PropTypes.number.isRequired,
imgHeight:React.PropTypes.number.isRequired
},
/*设置默认的props值*/
getDefaultProps: function(){
return {
direction:'right',
interval: 1000,
boxStyle:'content'
};
},
/*初始化state值*/
getInitialState : function(){
return{
activeIndex:1,
offsetDistance:this.props.direction == 'right' || this.props.direction == 'left' ? -this.props.imgWidth : -this.props.imgHeight,
pause:false,
flag:true
};
},
/*生命周期函数 在首次渲染之前*/
componentWillMount : function(){
this.direction = this.props.direction === 'left' || this.props.direction === 'right'? 'x' : 'y';
},
/*在真实的DOM被渲染出来后*/
componentDidMount : function(){
this.autoPlay();
},
/*组件被移除之前*/
componentWillUnmount : function(){
clearTimeout(this.timeOuter);
clearInterval(this.timer);
},
autoPlay : function(){
switch(this.props.direction){
case 'right' :
this.timerOuter=setTimeout(this.playRight,this.props.interval);
this.direction='x';
break;
case 'left' :
this.timerOuter=setTimeout(this.playLeft,this.props.interval);
this.direction='x';
break;
case 'top' :
this.timerOuter=setTimeout(this.playLeft,this.props.interval);
this.direction='y';
break;
case 'bottom':
this.timerOuter=setTimeout(this.playRight,this.props.interval);
this.direction='y';
break;
};
},
/*对不同方向做的相应模板上样式的处理*/
directionHandle : function(){
if(this.direction === 'y'){
return {top : this.state.offsetDistance+'px',width : this.props.imgWidth,height : this.props.imgHeight*(this.props.number+2)};
}else {
return {left : this.state.offsetDistance+'px',width : this.props.imgWidth*(this.props.number+2),height : this.props.imgHeight};
}
},
/*鼠标滑入,滑出*/
mouseHandle : function(e){
if(e.type === 'mouseover'){
this.setState({pause : true});
}else if(e.type === 'mouseleave'){
this.setState({pause : false});
this.autoPlay();
}
},
/*圆点显示效果*/
checkDots : function(index){
var activeIndex;
if(this.state.activeIndex === this.props.number+1){
activeIndex = 1;
}else if(this.state.activeIndex === 0){
activeIndex = this.props.number;
}else {
activeIndex = this.state.activeIndex;
}
return index+1 === activeIndex? 'dots active' : 'dots';
},
/*鼠标滑入圆点*/
dotsHover : function(index){
clearInterval(this.timer);
this.setState({activeIndex:index+1});
this.position();
},
/*向右或向下*/
playRight: function(indexIn){
if(this.state.flag){
var index=indexIn?indexIn:this.state.activeIndex+1;
this.setState({activeIndex:index});
this.position();
}
},
/*向左或向上*/
playLeft: function(indexIn){
if(this.state.flag){
var index=indexIn?indexIn:this.state.activeIndex-1;
this.setState({activeIndex:index});
this.position();
}
},
/*运动效果*/
position: function(){
this.setState({flag:false});
this.timer = setInterval(function(){
if(this.direction === 'x'){
var boxDistance = this.props.imgWidth;
}else {
var boxDistance = this.props.imgHeight;
}
var offsetDistance = this.state.offsetDistance;
if(Math.abs(offsetDistance-(-boxDistance*this.state.activeIndex)) <= 0.09){
offsetDistance = -boxDistance*this.state.activeIndex;
clearInterval(this.timer);
this.setState({flag:true});
if(this.state.activeIndex > this.props.number){
offsetDistance = -boxDistance;
this.setState({activeIndex : 1});
}else if(this.state.activeIndex === 0){
offsetDistance = -boxDistance*this.props.number;
this.setState({activeIndex : this.props.number});
}
this.setState({offsetDistance:offsetDistance});
if(!this.state.pause){
this.autoPlay();
}
}else{
offsetDistance = offsetDistance-(boxDistance*this.state.activeIndex-Math.abs(offsetDistance))/30;
this.setState({offsetDistance:offsetDistance});
}
}.bind(this),10);
},
/*点击向左按钮*/
left: function(){
var oldIndex=this.state.activeIndex;
this.playLeft(oldIndex-1);
},
/*点击向右按钮*/
right: function(){
var oldIndex=this.state.activeIndex;
this.playRight(oldIndex+1);
},
render : function(){
var _this = this;
return (<div className={this.props.boxStyle} style={{width:this.props.imgWidth, height:this.props.imgHeight}} onMouseOver={this.mouseHandle} onMouseLeave={this.mouseHandle}>
<span className="leftIcon" onClick={this.left}></span>
<span className="rightIcon" onClick={this.right}></span>
<div className="dots-wrap">
{
React.Children.map(this.props.children,function(elem,index){
return (<span className={_this.checkDots(index)} onMouseOver={_this.dotsHover.bind(_this,index)}></span>);
})
}
</div>
<ul style={this.directionHandle()}>
{this.props.children[this.props.number-1]}
{this.props.children}
{this.props.children[0]}
</ul>
</div>);
}
});
var LunBoComponent = React.createClass({
propsTypes : {
lunboObject : React.PropTypes.object.isRequired,
imgArray : React.PropTypes.array.isRequired,
linkArray : React.PropTypes.array
},
render : function(){
return (
<LunBoControl interval={this.props.lunboObject.interval} number={this.props.lunboObject.number} boxStyle={this.props.lunboObject.boxStyle} imgWidth={this.props.lunboObject.imgWidth} imgHeight={this.props.lunboObject.imgHeight} direction={this.props.lunboObject.direction}>
{
this.props.imgArray.map(function(item,index){
return <li key={index}><a href={this.props.linkArray[index]}><img width={this.props.lunboObject.imgWidth} height={this.props.lunboObject.imgHeight} src={item}/></a></li>;
}.bind(this))
}
</LunBoControl>
);
}
});
module.exports = LunBoComponent;
/*引用按以下方式*/
var LunBoComponent = require('./lunbo.jsx');
ReactDOM.render(<LunBoComponent lunboObject={data.lunboObject} imgArray={data.imgArray} linkArray={data.linkArray}/>, document.getElementById('wrapper'));
3.lunbo.less
li {
float: left;
margin: 0;
padding: 0;
font-size: 12px;
}
img {
vertical-align: top;
}
#wrapper > div {
overflow: hidden;
position: relative;
margin: 0 auto;
margin-top: 50px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
.lunbo-item {
float: left;
}
.leftIcon {
position: absolute;
display: inline-block;
width: 25px;
height: 25px;
transform: rotate(-45deg);
top: 162px;
left: 10px;
border-top: 3px solid #00ffcc;
border-left: 3px solid #00ffcc;
z-index: 999;
text-indent: -100%;
cursor: pointer;
}
.rightIcon {
position: absolute;
display: inline-block;
width: 25px;
height: 25px;
transform: rotate(45deg);
top: 162px;
right: 10px;
border-right: 3px solid #00ffcc;
border-top: 3px solid #00ffcc;
z-index: 999;
text-indent: -100%;
cursor: pointer;
}
.dots {
display: inline-block;
width: 16px;
height: 16px;
background: #eee;
border-radius: 8px;
margin-right: 8px;
float: left;
cursor: pointer;
}
.dots.active {
background: #000;
}
.dots-wrap {
overflow: hidden;
position: absolute;
z-index: 99;
bottom: 10px;
right: 20px;
}