react 移动端轮播图

slider

一组轮播的区域

何时使用

  • 主要是针对于移动端
  • 常用于一组图片或卡片轮播

demo演示

[ 暂无]

基本使用方法

js:

 import PuiSlider from './pui-slider'
  render(){
     return <div className="wrap" id="wrap">
                 <PuiSlider currentIndex="2"  smallDot={true} autoSpeed="2000" autoSlide={true} wrapHeight="600">
	                <div>1</div>
	                <div>2</div>
                 </PuiSlider>
             </div>
 }
 

cs:

  .pansliderBox{
  position: relative;
  .puiSlider{
    @include flex-box;
    flex-wrap: nowrap;
    -webkit-flex-wrap: nowrap;
    .sliderItem{
      width: 100%;
      height: 200px;
      img{
        width: 100%;
        height: 100%;
      }
    }

  }
  .sliderDot{
    position: absolute;
    bottom: 20px;
    left: 0;
    z-index: 20;
    width: 100%;
    height: 10px;
    display: block;
    font-size: 0;
    text-align: center;
    li{
      width: 12px;
      height: 12px;
      border-radius: 50%;
      background: #fff;
      display: inline-block;
      margin: 6px;
      transition: .25s;
      -webkit-transition: .25s;
      position: relative;
      overflow: hidden;
    }
    li.active{
      width: 15px;
      background: #fef339;
      height: 6px;
      border-radius: 6px;
      transition: .25s;
      -webkit-transition: .25s;
      position: relative;
    }
  }

}

API

参数说明类型默认值是否比传其他
currentIndex当前从第几张开始轮播string1
autoSlide是否自动轮播booleantrue
smallDot是否有轮播点点跟随booleantrue
autoSpeed轮播速度string2000
wrapHeight轮播内容高度string750传入的是设计稿的实际高度

方法

[ 暂无]

源码

import React, { Component } from 'react';
export default class puiSlider extends Component {
    constructor(props) {
        super(props);
        const {currentIndex=1,swiper=30,smallDot=true,autoSlide=true,autoSpeed=2000,wrapHeight=750}=this.props;
        const itemWidth=((wrapHeight-0)/37.5)*(document.getElementsByTagName('html')[0].style.fontSize.replace(/[px]/g,'')-0);
        this.state={
            currentIndex: currentIndex-0, //当前展示第几张图片
            swiper:swiper-0,  //最小移动距离,才能切换下一页
            smallDot, //是否有小按钮
            autoSlide,//是否自动轮播
            autoSpeed:autoSpeed-0, //自动轮播定时器间隔
            itemWidth, //item的宽度
            speed:0,  //tanslate移动速度
            startX:"",  //水平滑动其实位置
            curX: "",  //水平实时移动位置
            moveX: "",  //水平移动位置
            distance:-((currentIndex-0)*itemWidth),  //水平移动距离
        }
    }
    componentDidMount(){
        let _this=this;
        const {wrapHeight}=_this.props;
        window.addEventListener('resize', function () {
            _this.setState({
                itemWidth:((wrapHeight-0)/37.5)*(document.getElementsByTagName('html')[0].style.fontSize.replace(/[px]/g,'')-0)
            })
        });
        if(this.props.children && this.props.children.length>1){
            this.play()
        }
    }
    //开启定时器,自动播放
    play=()=>{
        if(this.state.autoSlide){
            let _this=this;
            _this.timer=setInterval(()=>{
                let currentIndex=_this.state.currentIndex;
                _this.setIndex(currentIndex+1);
            },_this.state.autoSpeed);
        }

    }
    //关闭定时器
    pause=()=>{
        if(this.state.autoSlide){
            clearInterval(this.timer)
        }
    }
    //子组头尾克隆渲染件渲染
    renderChildren=(children)=>{
        const   appendedChildren = [
            children[children.length - 1],
            ...children,
            children[0]
        ];
        return  React.Children.map(appendedChildren,(child,index)=>{
            const childClone = React.cloneElement(child, {  });  //克隆子组件,并返回一个新的组件,arg(要克隆的组件,新组建增加的属性)
            return (
                <div className="sliderItem" key={index}>
                    {childClone}
                </div>
            )
        })
    }
    translate=(_this,time,distance)=>{
        _this.setState({
            distance,
            speed:time
        })
    }
    //上下切换下一页
    setIndex=(index)=>{
        const len=this.props.children.length;
        if(len>1){
            let nextIndex=index;
            this.translate(this,300,-(this.state.itemWidth*(nextIndex)))
            const _this=this
            function translateFunc()  {
                if (nextIndex == 0) {
                    nextIndex = len;
                    _this.translate(_this,0,-(_this.state.itemWidth*(nextIndex)))
                    _this.setState({
                        currentIndex:nextIndex,
                    })
                } else if (nextIndex == len + 1) {
                    nextIndex = 1;
                    _this.translate(_this,0,-(_this.state.itemWidth*(nextIndex)))
                    _this.setState({
                        currentIndex:nextIndex,
                    })
                }else{
                    _this.setState({
                        currentIndex:nextIndex,
                    })
                }
                _this.refs.puiSlider.removeEventListener('webkitTransitionEnd',translateFunc,false)
                _this.refs.puiSlider.removeEventListener('transitionend',translateFunc,false)
            }
            this.refs.puiSlider.addEventListener('webkitTransitionEnd',translateFunc,false)
            this.refs.puiSlider.addEventListener('transitionend',translateFunc,false)
        }
    }
    touchStart=(e)=>{
        this.pause()
        this.setState({
            startX: e.touches[0].pageX
        })
    }
    touchMove=(e)=>{
        this.pause()
        e.preventDefault();
        let curX = e.touches[0].pageX;
        let moveX = curX - this.state.startX;
        let distance = -(this.state.currentIndex * this.state.itemWidth - moveX);
        this.setState({
            curX,
            moveX,
            distance
        })
    }
    touchEnd=()=>{
        this.play()
        if(Math.abs(this.state.moveX)>this.state.swiper){
            if(this.state.moveX>0){
                this.setIndex(this.state.currentIndex-1)
            }else{
                this.setIndex(this.state.currentIndex+1)
            }
        }else{
            this.setIndex(this.state.currentIndex)
        }
    }
    render() {
        const {children}=this.props;
        let unionStyle={
            WebkitTransform:  'translate3d(' + this.state.distance  + 'px,'+0+'px,'+0+'px)',
            transform:  'translate3d(' + this.state.distance + 'px,'+0+'px,'+0+'px)',
            WebkitTransition: 'all ' + this.state.speed+ 'ms ' + 'ease',
            transition: 'all ' + this.state.speed + 'ms ' + 'ease',
        }
        return (
            <div className="pansliderBox">
                {
                    (children && children.length>1) ?
                        <div ref="puiSlider" className="puiSlider" style={unionStyle} onTouchStart={e=>this.touchStart(e)} onTouchMove={e=>this.touchMove(e)} onTouchEnd={e=>this.touchEnd(e)}>{this.renderChildren(children)}</div>
                        :
                        <div ref="puiSlider" className="puiSlider">
                            <div className="sliderItem">{children}</div>
                        </div>
                }
                {
                    (this.state.smallDot && children && children.length>1) ?
                    <ol className="sliderDot">
                        {children.length>1 && children.map((item,index)=>(
                            <li className={this.state.currentIndex==(index+1) ? 'active' : ''} key={index}>{index}</li>
                        ))}
                    </ol>
                    :
                   <ol className="sliderDot">
                       <li className='active' key={1}>1</li>
                   </ol>
                }
            </div>
        );
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值