zoukankan      html  css  js  c++  java
  • ListArea滚动组件的实现

    先上代码:

    import React from 'react';
    
    export default class ListArea extends React.Component {
      state = {
        currentIndex: 0,
        interval: 3000,
        suspend: false
      };
    
      componentDidMount() {
        this.props.list.length > 1 && this.initAnimation();
      }
    
      componentDidUpdate(prevProps, prevState) {
        this.props.list.length > 1 && !this.timer && this.initAnimation();
      }
    
      componentWillUnmount() {
        this.timer && clearInterval(this.timer);
      }
    
      mouseEnter() {
        this.props.isSuspend && this.setState({suspend: true});
      }
    
      mouseLeave() {
        this.props.isSuspend && this.setState({suspend: false});
      }
    
      initAnimation() {
        this.timer = setInterval(() => {
          const firstElem = this.firstElem;
          if (!this.state.suspend && firstElem) {
            if (this.props.isCarousel) {
              firstElem.style.marginLeft = `${-firstElem.offsetWidth}px`;
            }else firstElem.style.marginTop = `${-firstElem.offsetHeight}px`;
    
            // 等待css动画执行完毕后刷新数据
            setTimeout(() => {
              const {list, getList} = this.props;
              let {currentIndex} = this.state;
    
              if (getList) {
                // 数据小于临界值时自动请求下一页数据
                // 若最后一页数据为0或者接口异常未返回数据时,数组长度不会发生变化
                // 所以每隔n秒触发动画并查询数据长度时若数据长度持续位于临界值之下时就应该持续请求后台数据
                if (list.length - currentIndex <= 5) getList();
                if (list.length - currentIndex === 1) clearInterval(this.timer);
    
                this.setState({currentIndex: currentIndex + 1});
    
              }else this.setState({currentIndex: list.length - currentIndex === 1 ? 0 : currentIndex + 1});
    
            }, 600);
          }
        }, this.state.interval);
      }
    
      render() {
        const {className, list, contentCount = 1, item, getList} = this.props;
        const {currentIndex} = this.state;
        const _list = getList ? list : [...list, ...list];
        return (
          <div className={className}
               onMouseEnter={this.mouseEnter.bind(this)}
               onMouseLeave={this.mouseLeave.bind(this)}
          >
            {
              _list.map((l, i) => i >= currentIndex && i < contentCount + currentIndex + 1 && item(l, i, ref => {if (i === currentIndex) this.firstElem = ref}, currentIndex))
            }
          </div>
        )
      }
    }

    分析:

    默认interval没3秒滚动一帧,suspend:false滚动,当前索引currentIndex:0,

    componentDidMount中 传入的list条数>1时进行初始化动画initAnimation()(此处可以优化下:传入contentCount,n条时进行初始化轮播)

    mouseEnter()鼠标移入后suspend=true,不滚动,mouseLeave()鼠标移出后suspend=false滚动。

    滚动的动画效果,使用transition。

    .transition {
      -webkit-transition: all .5s ease;
      -o-transition: all .5s ease;
      -moz-transition: all .5s ease;
      transition: all .5s ease;
    }

    在行中引入

    isCarousel为传入的滚动方向,有传则方向为从右向左轮播,没传则方向从下往上轮播。

    滚动使用css3效果,滚动到下一帧后更新展示数据。

     

    欢迎一起交流!
    【http://wuhairui.cnblogs.com/】

  • 相关阅读:
    Pikachu-File Inclusion模块
    Pikachu-RCE模块
    Pikachu-CSRF模块
    Pikachu-暴力破解模块
    Pikachu-XSS模块与3个案例演示
    将Word文档发布至博客园随笔
    DVWA-全等级XSS(反射型、存储型)
    DVWA-sql注入(盲注)
    DVWA-全等级验证码Insecure CAPTCHA
    管理页面的 setTimeout & setInterval
  • 原文地址:https://www.cnblogs.com/wuhairui/p/13679075.html
Copyright © 2011-2022 走看看