专栏首页菜鸟计划写一个简单的轮播组件

写一个简单的轮播组件

直接上代码

App.js文件

let list = [
    {
        id: 1,
        img: require('./static/image/one.jpg')
    },
    {
        id: 2,
        img: require('./static/image/two.jpg')
    },
    {
        id: 3,
        img: require('./static/image/three.jpg')
    }
];
render() {
    return (
        <div>
            <Banner list={list}></Banner>
        </div>
    );
}

banner.js文件
import React from 'react';
import PropTypes from 'prop-types';
import {Button} from 'antd'
import '../static/css/banner.scss'

export default class Banner extends React.Component{
    //设置默认值
    static defaultProps = {
        list: [],
        interval: 3000,
    }
    //设置默认规则
    static propTypes = {
        list: PropTypes.array,
        interval: PropTypes.number
    }
    //初始化状态值
    constructor(){
        super();
        this.state = {
            step: 1,
            speed: '0.2s'
        }
    }
    //组件挂载前进行数据预处理
    componentWillMount() {
        this.list = [this.props.list[this.props.list.length - 1], ...this.props.list, this.props.list[0]];
    }
    //组件挂载完成触发事件
    componentDidMount() {
        this.autoMove();
    }
    //组件更新前进行判断处理
    componentWillUpdate(nextProps, nextState, nextContext) {
        if (nextState.step >= this.list.length) {
            this.setState({
                step: 1,
                speed: '0s'
            });
        }
        if (nextState.step === -1) {
            this.setState({
                step: this.list.length - 2,
                speed: '0s'
            });
        }
    }
    //组件完成更新进行判断处理
    componentDidUpdate(prevProps, prevState, snapshot) {
        if(this.state.step === 1 && this.state.speed === '0s'){
            //js设置transition,不能在主栈队列执行时候遇到多次,这样渲染以最后一次为主,此时我们可以把第二次操作移动到EventQueue中。
            let delayTimer = setTimeout(()=> {
                this.setState({
                    step: this.state.step+1,
                    speed: '0.2s'
                });
            }, 50);
        }
        if (this.state.step === 3 && this.state.speed === '0s') {
            let delayTimer = setTimeout(()=> {
                this.setState({
                    step: this.state.step - 1,
                    speed: '0.2s'
                });
            }, 50);
        }
    }
    autoMove = ()=> {
        this.autoTime = setInterval(()=> {
            this.setState({
                step: this.state.step+1
            })
        }, this.props.interval)
    }
    handleClick = (e)=> {
        if (e.target.tagName === 'BUTTON') {
            let dir = e.target.getAttribute('dir');
            this.setState({
                step: dir === 'LEFT' ? this.state.step - 1 : this.state.step+1,
                speed: '0.2s'
            })
        }
    };
    render() {
        let wrapperStyle = {
          width: `${this.list.length*1000}px`,
          left: `${-this.state.step*1000}px`,
          transition: `left ${this.state.speed} linear 0s`
        };
        return (
            //利用事件委托统一处理
            <div className={'banner_container'} onMouseEnter={event => {clearInterval(this.autoTime)}} onMouseLeave={this.autoMove} onClick={this.handleClick}>
                <div className={'wrapper'} style={wrapperStyle}>
                    {
                        this.list.map((item,index) => {
                            let {img} = item;
                            return (
                                <div className={'slide'} key={index}>
                                    <img src={img}/>
                                </div>
                            )
                        })
                    }
                </div>
                <Button dir={'LEFT'}>左</Button>
                <Button dir={'Right'}>右</Button>
            </div>
        )
    }
}
banner.scss文件
.banner_container{
  margin: 20px auto;
  width: 1000px;
  height: 300px;
  overflow: hidden;
  position: relative;
  .wrapper{
    position: absolute;
    left: 0;
    top: 0;
    width: 3000px;
    height: 300px;
    .slide{
      font-size: 14px;
      width: 1000px;
      height: 300px;
      line-height: 300px;
      text-align: center;
      float: left;
      img{
        background:no-repeat center;
        width: 100%;
        height: 100%;
      }
    }
  }
  button:nth-child(2){
    position: absolute;
    left: 0;
    bottom: 0;
  }
  button:nth-child(3){
    position: absolute;
    right: 0;
    bottom: 0;
  }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一款轮播组件的诞生

    早在几个月前,就想自己动手写个轮播图组件,因此也看了许多文章,断断续续过了几个月,今天终于有时间腾出手来给此插件做个总结,因此有了这篇文章。话不多说,先上 De...

    小皮咖
  • 前端|Bootstrap 实例 - 简单的轮播插件

    Bootstrap 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式。除此之外,内容也是足够灵活的,可以是图像、内嵌框架、视频或者其他您想要...

    算法与编程之美
  • 编写一个简单的JQuery插件

    lpe234
  • 写一个简单的webserver

    基于 Python3 写的极简版 webserver。用于学习 HTTP协议,及 WEB服务器 工作原理。笔者对 WEB服务器 的工作原理理解的比较粗浅,仅是基...

    py3study
  • vue2.0 + element-ui 实战项目-实现一个简单的轮播图(六)

    自从用饿了么框架重构项目以来,遇到 很多问题,我都有一一记录下来,现在特喜欢这个框架,说实话,如果你是用了vue这个技术栈的话,一定要用饿了么的pc端框架哦,遇...

    王小婷
  • 一个简单的python读写文件脚本

    艳艳代码杂货店
  • 一个简单的python读写文件脚本

    代码伴一生
  • vue 实现一个简单的栅格组件

    参考iview, ant-design 的栅格组件,发现两者的基础思路是一致的。 这里通过实现一个简化版的栅格组件做总结.

    copy_left
  • 开发一个简单的 Vue 弹窗组件

    定义完 HTML 结构,还得定义组件的 props 属性,用来接收父组件的传参,以方便在父组件通过属性来控制弹窗。

    谭光志
  • 一个最简单的jQuery插件编写历程

    第一次写jQuery插件,简直无从下手,好在一步一步从简单到复杂(对我来说挺复杂的),终于理解了jQuery插件的写法规则,并最终以一个新闻式插件面世。尤其感谢...

    用户1148399
  • 写一个图片轮播效果的Demo(自动播放)附代码

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

    大黄大黄大黄
  • 写一个简单的WEB框架

    前面都是从httpserver中添加功能,下面希望把添加web功能写成框架的形式,如果进行开发,只需要响应的功能模块就行,而不是在httpserver中改写。

    DC童生
  • 手写一个简单的SpringBoot Starter

    现在各种自定义的starter屡见不鲜,也许就需要自己来自定义一个starter了。学习一下starter的构建必备

    zhaozhen
  • 封装一个超级简单的vue分享组件

    更新: 2018-5月起 jiathis关闭分享功能,请使用 http://sharesdk.mob.com/ 或搜索其他社会化分享类库

    mafeifan
  • 你用过不写代码就能完成一个简单模块的组件么?

    抛开业务来说,这几种代码是我们项目中最最基本的代码了,每一个项目中都会出现大量的这种代码。那么你的项目中这种代码你是怎么写的呢?

    Java学习录
  • Android 打造一个丝滑的自动轮播控件

    现在很多的 App 都有自动轮播的 banner 界面,用于展示广告图片或者显示当前比较热门的一些活动,除了具备比较酷炫的效果之外,通过轮播的方式来减少对界面的...

    developerHaoz
  • 一个简单的 Chrome 插件

    之前做秒杀器的时候,使用的是 WPF 客户端,借助 HttpWebRequest 来实现远程调用。 后来看到别人抢火车票的软件是一个 Chrome 插件,发现这...

    用户1172223
  • vue封装一个简单的div框选时间的组件

    技术需要积累,有时间我把我之前写的还不错的组件都开源出来。并尝试vue和react 两种方式的组件封装。今天简单写下鼠标框选div选中效果的封装吧。

    Java帮帮
  • 写一个简单的配置文件和日志管理(shell)

    共4个文件,服务端一个UpdateServer.conf配置文件和一个UpdateServer脚本,客户端一个UpdateClinet.conf配置文件和一个U...

    jianghaibobo

扫码关注云+社区

领取腾讯云代金券