import React, { useRef, useState, useEffect } from 'react'
import './index.less'
import smoothscroll from 'smoothscroll-polyfill'
interface List {
id: string,
text: string
}
export default () => {
const [ButtonList] = useState<List[]>(
[
{
id: 'n1',
text: '推荐'
},
{
id: 'n2',
text: '女装'
},
{
id: 'n3',
text: '运动'
},
{
id: 'n4',
text: '美妆'
},
{
id: 'n5',
text: '男装'
},
{
id: 'n6',
text: '鞋靴'
},
{
id: 'n7',
text: '数码'
},
{
id: 'n8',
text: '母婴'
},
{
id: 'n9',
text: '家电'
},
{
id: 'n10',
text: '国际'
},
]
);
const [ContentList] = useState<List[]>(
[
{
id: 'c1',
text: '推荐'
},
{
id: 'c2',
text: '女装'
},
{
id: 'c3',
text: '运动'
},
{
id: 'c4',
text: '美妆'
},
{
id: 'c5',
text: '男装'
},
{
id: 'c6',
text: '鞋靴'
},
{
id: 'c7',
text: '数码'
},
{
id: 'c8',
text: '母婴'
},
{
id: 'c9',
text: '家电'
},
{
id: 'c10',
text: '国际'
},
]
);
// ref
const navLine = useRef<HTMLDivElement>(null)
const tabRef = useRef<HTMLDivElement>(null)
const navListParent = useRef<HTMLDivElement>(null)
const contentScrollWrap = useRef<HTMLDivElement>(null)
const GetContentScrollWrap = () => {
return contentScrollWrap.current as HTMLDivElement
}
const GetTabRef = () => {
return tabRef.current as HTMLDivElement
}
const GetNavLine = () => {
return navLine.current as HTMLDivElement
}
const GetNavListPart = () => {
return navListParent.current as HTMLDivElement
}
// 变量
let swiperStartX: number = 0
let swiperMoveX: number = 0
let num: number = 0
let date: number = 0
let startX: number = 0
let flag: boolean = false
// 状态
const [Index, setIndex] = useState<number>(0)
const [swiperItemWidth, setContentListWidth] = useState<number>(0)
const [tabItemWidth, setNavListWidth] = useState<number>(0)
const Cut = (key: number) => {
setIndex(key);
}
const FnStart = (e: React.TouchEvent) => {
date = Date.now()
num = 0
GetContentScrollWrap().style.transition = 'none'
swiperStartX = GetContentScrollWrap().offsetLeft - e.changedTouches[0].pageX;
startX = e.changedTouches[0].pageX;
GetContentScrollWrap().ontouchmove = FnMove;
}
const FnMove = (e: TouchEvent) => {
swiperMoveX = e.changedTouches[0].pageX;
if (num === 0) {
flag = true
}
num++
if (GetContentScrollWrap().offsetLeft > 0 || GetContentScrollWrap().offsetLeft < -swiperItemWidth * (ButtonList.length - 1)) return false
if (flag) {
GetContentScrollWrap().style.left = swiperMoveX + swiperStartX + 'px'
GetContentScrollWrap().ontouchend = FnEnd;
}
}
const FnEnd = (e: TouchEvent) => {
flag = false;
// let num = Index
GetContentScrollWrap().style.transition = 'left .3s linear'
if (Math.abs(startX - e.changedTouches[0].pageX) > swiperItemWidth / 2 || Date.now() - date < 300) {
// if (startX - e.changedTouches[0].pageX < 0) {
// if (Index > 0) {
// num = Index - 1
// } else {
// num = 0
// }
// } else if (Index + 1 > ButtonList.length - 1) {
// num = ButtonList.length - 1
// } else {
// num = Index + 1
// }
// setIndex(num)
setIndex(startX - e.changedTouches[0].pageX < 0 ? Index > 0 ? Index - 1 : 0
: Index + 1 > ButtonList.length - 1 ? ButtonList.length - 1 : Index + 1)
}
GetContentScrollWrap().style.left = -Index * swiperItemWidth + 'px'
GetContentScrollWrap().ontouchmove = null;
GetContentScrollWrap().ontouchend = null;
}
// 监听Index
useEffect(() => {
let lineTo = tabItemWidth * Index;
GetNavLine().style.transform = `translate3d(${lineTo}px,0,0)`;
GetNavLine().style.transition = '.1s';
//控制tab滚动
let tabTo = lineTo - tabItemWidth;
GetTabRef().scrollTo({ left: tabTo, behavior: "smooth" });
GetTabRef().style.transition = '.5s';
// 控制swiper滚动
let swiperTo = swiperItemWidth * Index;
GetContentScrollWrap().style.left = -swiperTo + 'px';
GetContentScrollWrap().style.transition = '.5s';
}, [Index]);
// 解决移动端 scrollTo 的 behavior: "smooth" 无效的问题
useEffect(() => {
smoothscroll.polyfill();
// swiper元素宽度
setContentListWidth((GetContentScrollWrap().children[0] as HTMLDivElement).offsetWidth)
// nav列表宽度
setNavListWidth((GetNavListPart().children[0] as HTMLDivElement).offsetWidth)
}, [])
return (
<div className="v-home-wrap">
<div className='nav-wrap' ref={tabRef}>
<div className="nav" ref={navListParent}>
{ButtonList.map((item, index) =>
<div key={item.id} onClick={() => Cut(index)} className={Index === index ? "nav-list ac" : "nav-list"}>{item.text}</div>
)}
<div className="nav-line" ref={navLine}></div>
</div>
</div>
<div className="content-wrap">
<div className="content" onTouchStart={FnStart} ref={contentScrollWrap}>
{ContentList.map((item, index) =>
<div className='content-list' key={item.id}>{item.text}</div>
)}
</div>
</div>
</div>
)
}