zoukankan      html  css  js  c++  java
  • 继上一篇随笔,优化3张以上图片轮播React组件

    import React from 'react';
    import PropTypes from 'prop-types';
    
    import {getSwipeWay} from '../utils/swipe';
    
    //imgs         : 图片src数组
    //playTime  : 轮播下一张图片的时间间隔
    //notAuto   : 是否开启自动轮播 默认开启 false
    
    const PropsChecker = {
        imgs      : PropTypes.array.isRequired,
        playTime : PropTypes.number,
        notAuto  : PropTypes.bool,    
    };
    
    class Carousel extends React.Component {
        static defaultProps = {
            playTime : 5000,
            notAuto  : false,
        }
        
        constructor(args){
            super(args);
            this.state = {
            };
            //缓存各个currIndex的ul之后的标签
            this.storeElements = {};
            //判断滑动手势
            this.swipeWay = getSwipeWay(50);//闸值50
            //图片显示的限制
            this.limit = 3;
            //当前展示的图片
            this.currIndex = 0;
            //展示的数组
            this.showImgs = [];
            //手势滑动坐标
            this.position = {
                x1:0,
                x2:0,
                y1:0,
                y2:0,
            };
            //<ul>
            this.Ul = null;
            //禁止在transiton的期间操作
            this.isTransition = false;
            //定时器
            this.timer = 0;
        }
    
        componentDidMount(){
            this.autoPlay();
        }
    
        componentWillUnmount(){
            clearTimeout(this.timer);
        }
    
        getHead(arr){
            if(Array.isArray(arr)){
                return arr[0];
            }
            console.error('非数组');
        }
    
        getLast(arr){
            if(Array.isArray(arr)){
                const len = arr.length;
                return arr[len-1];            
            }
            console.error('非数组');
        }
    
        calcIndex(){
            const {imgs}     = this.props;
            const len          = imgs.length;
            const limit     = this.limit;
            const currIndex = this.currIndex;
    
            if(currIndex == 0){
                this.showImgs = imgs.slice(0,limit - 1);
                this.showImgs.unshift(this.getLast(imgs));
                return;
            }
    
            if(currIndex == len - 1){
                this.showImgs = imgs.slice(len -2 ,len);
                this.showImgs.push(this.getHead(imgs));
                return;
            }
    
            this.showImgs = imgs.slice(currIndex -1 , currIndex + limit -1);
    
        }
    
        changeCurrIndex(flag){
            const {imgs} = this.props;
            const last    = imgs.length -1;
            const currIndex = this.currIndex;
            if(flag === '-'){
                this.currIndex = currIndex == 0 ? last : currIndex -1 ;
                return;
            }
    
            if(flag === '+'){
                this.currIndex = currIndex == last ? 0 : currIndex + 1 ;
                return;
            }
        }
    
        ulTranslate(value){
            const Ul = this.Ul;
            if(Ul){
    
                if(Ul.style.webkitTranslate ){
                    Ul.style.webkitTranslate = value;
                }else{
                    Ul.style.translate = value;
                }
    
            }
    
        }
    
        createUl(){
            const currIndex     = this.currIndex;
            const storeElements = this.storeElements;
    
            //缓存这些标签,避免多次创建,很有必要
            if(!storeElements[currIndex]){
                //要保证<ul>key不同 也就是每次轮播后都要是新的标签,有损性能
                const Ul = (<ul onTouchEnd={this.touchEnd} 
                        onTouchMove={this.touchMove} 
                        onTouchStart={this.touchStart} 
                        onTransitionEnd={this.transitionEnd} ref={(ele)=>this.Ul=ele} key={currIndex}>
    
                        {this.createLis()}
                    </ul>);
    
                storeElements[currIndex] = Ul;
            }
    
            return storeElements[currIndex];
        }
    
        createLis(){
            this.calcIndex();        
            const imgs = this.showImgs;
    
            return imgs.map((src,i)=>{
                const liStyle = {
                    // translate:(-i)+'00%',
                    translate:( (i+'00') - 100 ) + '%',
                    WebkitTranslate:( (i+'00') - 100 ) + '%',
                };
    
                return <li className='item' key={i} style={liStyle} ><img src={src}  /></li>;
            });
    
        }
    
        touchStart = (e) => {
            if(this.isTransition){
                return;
            }
    
            clearTimeout(this.timer);
    
            const {clientX,clientY} = e.touches[0];
            this.position.x1 = clientX;
            this.position.y1 = clientY;
        }
    
        touchMove = (e) => {
    
        }
    
        touchEnd = (e) => {
            if(this.isTransition){
                return;
            }
    
            const {clientX,clientY} = e.changedTouches[0];
            this.position.x2 = clientX;
            this.position.y2 = clientY;
    
            const {x1,x2,y1,y2} = this.position;
    
            const direction = this.swipeWay(x1,x2,y1,y2);
    
            if( direction === 'Left'){
                this.changeCurrIndex('+');
                this.isTransition = true;
                this.ulTranslate('-100%');
            }
    
            if(direction === 'Right'){
                this.changeCurrIndex('-');
                this.isTransition = true;
                this.ulTranslate('100%');
            }
        }
    
        next(){
            this.changeCurrIndex('+');
            this.isTransition = true;
            this.ulTranslate('-100%');        
        }
    
        autoPlay(){
            const {playTime,notAuto} = this.props;
            if(!notAuto){
                this.timer = setTimeout(()=>{
                    this.next();
                },playTime);            
            }
        }
    
        transitionEnd = (e) => {
            this.forceUpdate(()=>{
                this.isTransition = false;
                this.autoPlay();            
            });
        }
    
        render(){
    
            return (<div className='mm-carousel' >
                {this.createUl()}
            </div>);
        }
    }
    
    export default Carousel;
    
    Carousel.propTypes = PropsChecker;
  • 相关阅读:
    [Leetcode] Longest Substring Without Repeating Characters
    [Leetcode] Clone Graph
    [Leetcode] LRU Cache
    行转列
    微信 Demo
    微信开发-step by stemp
    知识库
    SSAS GUID 添加 行计数,非重复计数 等 遇到的莫名其妙的问题
    javascript 前段MVVM 框架
    微信接口开发
  • 原文地址:https://www.cnblogs.com/lantuoxie/p/8134127.html
Copyright © 2011-2022 走看看