react 简单轮播图实现
ul{
padding: 0;
margin: 0;
}
.swipper {
width: 50%;
background-color: #99a9bf;
position: relative;
overflow: hidden;
.swipper-item {
top:0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
display: inline-block;
text-align: center;
background-color: #00965E
}
.btn-prev{
position: absolute;
top: 50%;
left: 0;
margin-top: -13px;
width: 36px;
height: 36px;
z-index: 2;
}
.btn-next{
position: absolute;
top: 50%;
right: 0;
margin-top: -13px;
width: 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;
width: 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>
);
}
积累小的知识,才能成就大的智慧,希望网上少一些复制多一些原创有用的答案

浙公网安备 33010602011771号