首先:父元件Slider,三個子元件:SliderList、SliderArrows、SliderDots
目錄
index.js
import React,{Component} from 'react';
import ReactDOM,{render} from 'react-dom';
import Slider from "./Slider";
import './index.less'
import a from './1.jpg';
import b from './2.jpg';
import c from './3.jpg';
let items = [{src:a},{src:b},{src:c}];
ReactDOM.render(<Slider
delay={2}
speed={0.5}
autoplay={true}
dots={true}
arrows={true}
items={items}
/>,window.root);
複製程式碼
index.less
*{margin: 0;padding: 0}
ul,li{list-style: none}
.slider-container{
width:400px;
height:300px;
border:5px solid red;
margin:0 auto;
position: relative;
overflow: hidden;
ul{
position: absolute;height: 300px;left: 0;top: 0;
li{
width: 400px;height: 300px;float: left;
img{width: 100%;height: 100%;}
}
}
.slider-arrows{
position: absolute;
width: 100%;
height:40px;
top:50%;
transform: translateY(-50%);
left:0;
span{
width: 30px;height: 40px;line-height: 40px;display: block;
background: #ffffff;text-align: center;-webkit-user-select: none;
cursor: pointer;
&:nth-child(1){
float: left;
}
&:nth-child(2){
float: right;
}
}
}
.slider-dots{
position: absolute;width: 100%;left: 0;bottom: 20px;text-align: center;
span{
background: #ffffff;display: inline-block;width: 20px;height: 20px;
border-radius: 50%;margin: 3px;cursor: pointer;
&.active{
background: rgba(233,222,100,0.8);
}
}
}
}
複製程式碼
Slider.js
import React,{Component} from 'react';
import SliderList from "./SliderList";
import SliderArrows from "./SliderArrows";
import SliderDots from "./SliderDots";
export default class Slider extends React.Component {
constructor(){
super();
this.state = {index:0}// 表示當前是第幾張
}
go =(step)=>{ // 去哪 傳入要動幾個
let index = this.state.index+step;// 先加的
if(index > this.props.items.length){ // 當等於最後一張時 越界回到0
this.$ul.style.transitionDuration = '';// 清除ul上的動畫
this.$ul.style.left = 0;// 回到0處
setTimeout(()=>{// 等動畫移除後並且回到了0點 再增加回動畫時間(dom重新整理一般是30s)
this.$ul.style.transitionDuration = this.props.speed+'s';// 再增加回來這個動畫
index = 1;// 下一次該走1了
this.setState({index});
},30)
return;//因為設定了setTimeout所以要等待setTimeout後再設定最新狀態
}
if(index < 0){// 當小於第一張時 回到最後一張
this.$ul.style.transitionDuration = '';// 清除ul上的動畫
this.$ul.style.left = this.props.items.length*-1*400+'px';
setTimeout(()=>{
this.$ul.style.transitionDuration = this.props.speed+'s';
index = this.props.items.length -1;
this.setState({index});
},30);
return
}
this.setState({
index:index
})
}
turn = () =>{ // 輪播
this.timer = setInterval(()=>{
this.go(1)
},this.props.delay*1000);
}
componentDidMount(){ // 頁面載入完成後 看是否需要自動輪播
if(this.props.autoplay){
this.turn();
}
// 通過ulfs獲取sliderList中的ul元素(操作dom節點)
console.log(this.$ul = this.refs.list.refs.ul)
}
render(){
// 越界了並且只是第一個span加上active屬性
return (
<div className='slider-container' onMouseEnter={()=>{
clearInterval(this.timer);
}} onMouseLeave={()=>{
this.turn();
}}>
<SliderList ref='list' index={this.state.index} items={this.props.items} speed={this.props.speed}/>
{this.props.arrows?<SliderArrows go={this.go}/>:null}
{this.props.dots?<SliderDots go={this.go} items={this.props.items} index={this.state.index}/>:null}
</div>
)
}
}
複製程式碼
SliderArrows.js
import React,{Component} from 'react';
export default class SliderDots extends React.Component {
render(){
return (
<div className='slider-dots'>
{this.props.items.map((item,index)=>(
<span key={index} className={this.props.index===index?'active':''}
onClick={()=>{this.props.go(index-this.props.index)}}></span>
))}
</div>
)
}
}
複製程式碼
SliderDots.js
import React,{Component} from 'react';
export default class SliderDots extends React.Component {
render(){
// 越界了並且只是第一個span加上active屬性
return (
<div className='slider-dots'>
{this.props.items.map((item,index)=>(
<span key={index}
className={(this.props.index===index)||(this.props.index===this.props.items.length&&index===0)?'active':''}
onClick={()=>{this.props.go(index-this.props.index)}}></span>
))}
</div>
)
}
}
複製程式碼
SliderList.js
import React,{Component} from 'react';
export default class MessageBox extends React.Component {
render(){
let style={
width:(this.props.items.length+1)*400+'px', // 設定ul預設寬度
left:this.props.index*400*-1 + 'px', // 根據當前inedex 移動left值
transition:`left ${this.props.speed}s linear`
}
return (
<ul style={style} ref='ul'>
{this.props.items.map((item,index)=>(
<li><img src={item.src} key={index}/></li>
))}
{/*實現無縫輪播要再增加一張圖*/}
<li><img src={this.props.items[0].src} alt=""/></li>
</ul>
)
}
}
複製程式碼
附上效果圖
最後