zoukankan      html  css  js  c++  java
  • react 简单轮播图实现

    ul{
      padding: 0;
      margin: 0;
    }
    .swipper {
       50%;
      background-color: #99a9bf;
      position: relative;
      overflow: hidden;
      .swipper-item {
        top:0;
        left: 0;
        position: absolute;
         100%;
        height: 100%;
        display: inline-block;
        text-align: center;
        background-color: #00965E
      }
      .btn-prev{
        position: absolute;
        top: 50%;
        left: 0;
        margin-top: -13px;
         36px;
        height: 36px;
        z-index: 2;
      }
      .btn-next{
        position: absolute;
        top: 50%;
        right: 0;
        margin-top: -13px;
         36px;
        height: 36px;
        z-index: 2;
      }
      .nav{
        position: absolute;
        bottom: 10px;
        z-index: 2;
        left: 50%;
        transform: translateX(-50%);
        .nav-item{
          display: inline-block;
          border-radius: 50%;
          background-color: #FFAC38;
           10px;
          height: 10px;
          padding: 2px;
          opacity: .4;
          &:not(:last-child){
            margin-right: 5px;
          }
        }
        .is-active{
          opacity:1
        }
      }
    }
    

      

    import React, { useState, useEffect, useRef } from "react";
    import "./swipper.less";
    
    export default function Swipper(props) {
      const swipperStyle = {
        height: props.height
      };
      //动画运行速度
      // const [speed, setSpeed] = useState(props.speed);
    
      //当前选中项
      const [navIdx, setNavIdx] = useState(0);
      //获取列表项大小
      const liRef = useRef(null);
    
      //测试数据
      const [data, setData] = useState([
        {
          key: 1,
          value: "1"
        },
        {
          key: 2,
          value: "2"
        },
        {
          key: 3,
          value: "3"
        },
        {
          key: 4,
          value: "4"
        }
      ]);
      /**
       * 初始化LI位置
       */
      useEffect(() => {
        let list = data.map((item: any, index) => {
          item.xPort = index * (liRef.current as any).offsetWidth;
          return {
            ...item
          };
        });
        setData(list);
      }, []);
    
      /**
       * 前进
       */
      const handlePrev = () => {
        let domWidth = Math.abs((liRef.current as any).offsetWidth);
        let domCount = document.getElementsByClassName("swipper-item").length;
        let maxWidth = (domCount - 1) * domWidth - domWidth;
        let curIdx=navIdx;
        let list = data.map((item: any) => {
          if (item.xPort > maxWidth) {
            item.xPort = 0;
          } else {
            item.xPort = item.xPort + domWidth;
          }
          return {
            ...item
          };
        });
        if (curIdx - 1 < 0) {
          setNavIdx(domCount-1);
        } else {
          setNavIdx(curIdx - 1);
        }
        console.log(navIdx);
        setData(list);
      };
    
      /**
       * 后退
       */
      const handleNext = () => {
        let domWidth = Math.abs((liRef.current as any).offsetWidth);
        let domCount = document.getElementsByClassName("swipper-item").length;
        let list = data.map((item: any) => {
          if (item.xPort < 0) {
            item.xPort = (domCount - 1) * domWidth - domWidth;
          } else {
            item.xPort = item.xPort - domWidth;
          }
          return {
            ...item
          };
        });
        let curIdx=navIdx;
        if (curIdx + 1 >= domCount) {
          setNavIdx(0);
        } else {
          setNavIdx(curIdx + 1);
        }
        console.log(navIdx);
        setData(list);
      };
      /**
       * 根据点去跳转到具体的DIV
       */
      const getPanelByIdx = index => {
        //点击的那个项
        let domWidth = Math.abs((liRef.current as any).offsetWidth);
        let domCount = document.getElementsByClassName("swipper-item").length;
        let list = data.map(item => {
          return item;
        });
        let prevDom: any = list[index - 2];
        //选中的前一个DOM变为负数
        if (prevDom) {
          prevDom.xPort = -domWidth;
        }
        //选中的那个DOM变成0
        (list[index - 1] as any).xPort = 0;
        let idx = 1;
        //选中的后面的依次N*domWidth
        for (let i = index; i < domCount; i++) {
          (list[i] as any).xPort = idx * domWidth;
          idx++;
        }
        //选中的前面的前面的那些也要都处理掉
        if (prevDom && list[index - 3]) {
          //如果选中的前面那个就已经是第一个,就不再后续处理
          for (let i = 0; i < index - 2; i++) {
            (list[i] as any).xPort = idx * domWidth;
            idx++;
          }
        }
        setData(list);
        setNavIdx(index - 1);
      };
      return (
        <div>
          <div style={swipperStyle} className="swipper">
            <button className="btn-prev" onClick={handlePrev}>
              前进
            </button>
            <button className="btn-next" onClick={handleNext}>
              后退
            </button>
            <ul className="nav">
              {data.map((item: any, index) => {
                return (
                  <li
                    className={`nav-item ${navIdx === index ? "is-active" : ""}`}
                    key={index}
                    onClick={() => getPanelByIdx(item.key)}
                  ></li>
                );
              })}
            </ul>
            {data.map((item: any) => {
              return (
                <div
                  style={{
                    transform: item.xPort
                      ? `translateX(${item.xPort}px)`
                      : "translateX(0px)"
                  }}
                  ref={liRef}
                  className="swipper-item"
                  key={item.key}
                >
                  {item.value}
                </div>
              );
            })}
          </div>
        </div>
      );
    }
      
    

      

  • 相关阅读:
    HTML5
    js实现查找字符串中最多的字符的个数
    get和post的区别
    第十七篇 类的特殊成员
    第十八篇 面向对象修饰符
    MariaDB+Keepalived双主高可用配置MySQL-HA
    linux命令详解——crontab
    Java的内存泄漏
    jvm监控工具jconsole进行远程监控配置
    loadrunner执行场景时报Error -27040: Data Format Extension: Init: Internal error问题解决
  • 原文地址:https://www.cnblogs.com/llcdbk/p/13189505.html
Copyright © 2011-2022 走看看