zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

React.js简单轮播图组件封装

2023-02-18 16:41:46 时间

如何使用

https://player.bilibili.com/player.html?aid=370886286

轮播图

 /*
 *  imgUrl : 轮播图数据 
 *  speed  : 动画时间 
 *  step   :初始轮播图的位置
 *  width  :轮播图宽
 *  height :轮播图高 
 *  autoplay:是否自动轮播
 *  
 */
render(
   <div><Banner imgUrl={imgUrl} speed={500} step= {1} width={1170} height={400} interval={2000} autoplay={true}/></div>,
  document.getElementById("root")
)

banner.js

/* eslint-disable react/no-typos */

import React from "react"
import propTypes from "prop-types"
import "../css/banner.less"
export default class Banner extends React.Component {
    constructor(props) {
        super(props)
        let { imgUrl, speed, step, width, height, autoplay } = this.props

        // 克隆数组
        let imgUrlClone = []
        imgUrlClone = imgUrlClone.concat([].concat(imgUrl))
        imgUrlClone.push(imgUrl[0])
        imgUrlClone.unshift(imgUrl[imgUrl.length - 1])
        this.imgUrlClone = imgUrlClone
        this.state = {
            speed,
            step,
            width,
            height
        }
        if (autoplay) {
            this.timer = setInterval(() => {
                this.next()
            }, this.props.interval);
        }
    }

    static propTypes = {
        dataUrl: propTypes.array,
        speed: propTypes.number,
        spep: propTypes.number,
        width: propTypes.number,
        height: propTypes.number,

    }
    static defaultProps = {
        imgUrl: [],
        speed: 200,
        spep: 1,
        width: 1170,
        height: 400,
        autoplay: true
    }
    render() {
        let { width, height, step, speed } = this.state
        let swiperBoxSty = {
            width: `${this.imgUrlClone.length * width}px`,
            left: `${-step * width}px`,
            height: height + "px",
            transition: `all ${speed}ms linear`
        }
        this.swiperBoxSty = swiperBoxSty
        let commom = {
            width: width + "px",
            height: height + "px"
        }
        return <div className="container" style={commom} ref="box" onMouseEnter={this.removeInte} onMouseLeave={this.addInter}>
            <div className="swiper-box" style={swiperBoxSty}>
                {this.imgUrlClone.map((item, index) => {
                    return <div className="swiper-item" key={index}><img src={item} alt="" /></div>
                })}

            </div>
            <div className="swiper-arrow">
                <div className="arrowLeft iconfont iconqianjin1" ref="pre" onClick={this.prev}></div>
                <div className="arrowRight iconfont iconqianjin" ref="next" onClick={this.next}></div>
            </div>
            <div className="focus">
                {this.props.imgUrl.map((item, index) => {
                    if (step === this.imgUrlClone.length - 1) {
                        step = 1
                    }
                    if (step === 0) {
                        step = this.imgUrlClone.length - 2
                    }
                    return <div className={index + 1 === step ? "active" : ""} key={index}></div>
                })}

            </div>
        </div>
    }
    next = () => {
        let { step } = this.state
        if (step >= this.imgUrlClone.length - 1) {
            this.setState({
                step: 1,
                speed: 0
            })
        }
        setTimeout(() => {
            this.setState({
                step: this.state.step + 1,
                speed: this.props.speed
            })
        }, 0)

    }
    prev = () => {
        let { step } = this.state
        if (step <= 0) {
            this.setState({
                step: this.imgUrlClone.length - 2,
                speed: 0
            })
        }
        setTimeout(() => {
            this.setState({
                step: this.state.step - 1,
                speed: this.props.speed
            })
        }, 0)

    }
    removeInte = () => {
        clearInterval(this.timer)
    }
    addInter = () => {
        if(!this.props.autoplay)return
        this.timer = setInterval(() => {
            this.next()
        }, this.props.interval);
    }
   
}

banner.less

@font-face {
  font-family: "iconfont";
  src: url('//at.alicdn.com/t/font_1483779_y95pc2rnssm.eot?t=1591265219045');
  /* IE9 */
  src: url('//at.alicdn.com/t/font_1483779_y95pc2rnssm.eot?t=1591265219045#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALoAAsAAAAABqwAAAKZAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBEIENATYCJAMMCwgABCAFhG0HPBvZBcg+QRxjO4CWBEKoqC5QYQo700fuN3/uDcc0D29tBG9jb/N2twTk6jm+qqkCVGwkUHzjD+z5E+Y0xgMKd/n/u3S/Y0t4PpJ511Yyt5pq3vhJ0xu5lwtjD4eQGIWjwkElitKAzN76+msYvV4+QJk1gMDAv2SE/M2PYv8EOIHMk5CPXAMA9nmuyVdAB1L7NptTpUXH80jACQ60A9dkG8kAfIPuIkYlfZ0nUG9Yi8jm0MQ0pBVgWiDOODMgbYUVpcjVCtUTa4t4JqE23fgFPPHvx2/FSJNUZWDu1umgDT3f+v2MMUetPF/nRLGJjEWgELuT6R0xUbAx9cb4cmm1IqSrYg9X9ubqj/7xElENVDeC2TiT+AZLCb61QQIZVMvsCLCUMJ1PC6m6qfGA0Wm02ct+D3u9fP3SaT9dnPzy/vauC5/3Xr37+Dh4wFbCFwLq96r+b/1XSbR/Ddv7l8//kla7Kuj4XgJ/DFCR3/wDlb1eiCC4/PAbOq7NFfD15MGKAtu8oPbtnuBvqTZ2lV4DLLm0SqwcvVnfQWcilpc+lYC/XfW4uWtzNaFWl0ZSYwhZrUmiMIuo0mAZ1WqtoN6C4c0NOkgxUeow7zhCaPWBpNl7ZK0qRGF+UKVbDdVaI4Z621G3Z4Pp4Nl+iYZCm5jrhFvCp8imsqJ2Etmya0hTw7lZlCGPkYKWd3PD6KO8YkG4wopKUUKl8MhQdBm6riCBFGW0lFZSKmjTdTr1Js0SHmRtkJBBQTbCtI7gLIKP0sFK1vv8JMQscxnkQt1OdhaSQnx4okCT30AMG/1Ndb9yTWgFU6QoFEFJgocYikYhl0sggulRZciiaEoHkoE2OuxHtxq1583eD1QUTYDNOVLkKGquueGXuZ/mrgIAAAAA') format('woff2'), url('//at.alicdn.com/t/font_1483779_y95pc2rnssm.woff?t=1591265219045') format('woff'), url('//at.alicdn.com/t/font_1483779_y95pc2rnssm.ttf?t=1591265219045') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('//at.alicdn.com/t/font_1483779_y95pc2rnssm.svg?t=1591265219045#iconfont') format('svg');
  /* iOS 4.1- */
}
.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.iconqianjin:before {
  content: "\e61f";
}
.iconqianjin1:before {
  content: "\e6c5";
}
* {
  margin: 0;
  padding: 0;
}
.container {
  position: relative;
  width: 1170px;
  margin: 0 auto;
  overflow: hidden;
  height: 400px;
}
.container .swiper-box {
  display: flex;
  height: 400px;
  position: absolute;
  transition: all 1s linear;
}
.container .swiper-box .swiper-item {
  width: 100%;
  height: 100%;
}
.container .swiper-box .swiper-item img {
  width: 100%;
  height: 100%;
}
.container .swiper-arrow {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
.container .focus {
  height: 15px;
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
}
.container .focus div {
  width: 10px;
  height: 10px;
  border-radius: 5px;
  opacity: 1;
  background-color: white;
  margin-left: 10px;
}
.container .focus .active {
  background-color: black;
  opacity: 0.8;
}