react tab选项卡吸顶实现,直接上代码(代码有注释)
tsx代码
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState } from "react";
import DocumentTitle from 'react-document-title'
import styles from './styles.module.less'
// 双旦活动
const Holiday: React.FC<any> = () => {
const tabList = [
{
label:'礼物榜单',
value:0
},
{
label:'圣诞活动',
value:1
},
{
label:'元旦活动',
value:2
}
]
const [active,setactive] = useState<number>(0)
const [isFixed,setisFixed] = useState<boolean>(false)
//获得页面向左、向上卷动的距离
const getScroll = () => {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
useEffect(() => {
const btnList = document.getElementById('btnList')
const offsetTop = btnList?.offsetTop || 0 // offsetTop:元素到offsetParent顶部的距离(当前元素顶部距离最近父元素顶部的距离)
window.onscroll = function() {
if(getScroll().top >= offsetTop){ // 判断滚动高度是否大于等于 btnList的offsetTop
setisFixed(true) // 用于判断是否给btnList动态设置style
}else{
setisFixed(false)
}
}
}, [])
return (
<DocumentTitle title='双旦活动'>
<div className={styles.Holiday}>
<div className={styles.top}>
<div className={styles.btnList} id="btnList" style={isFixed ? { zIndex: "999",top: "0",position: "fixed", backgroundColor: "#fff" } : {}}>
{
tabList.map((item:any) => (
<div onClick={()=> setactive(item.value)}
key={item.value}
className={active === item.value ? styles.acitve : ''}>
{item.label}
</div>
))
}
</div>
</div>
<div className={styles.center}>
<div className={styles.centerBox}>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
<div>双旦活动</div>
</div>
</div>
</div>
</DocumentTitle>
)
}
export default Holiday;
less代码
.Holiday {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
.top{
width: 100vw;
height: 590px;
background: url('../../assets/toplistbg.png') no-repeat;
background-size: 100%;
position: relative;
.btnList{
width: 100vw;
padding: 20px 37px;
box-sizing: border-box;
position: absolute;
bottom: 28px;
height: 120px;
display: flex;
justify-content: space-between;
bottom: 20px;
>div{
&.acitve{
background: rgba(1, 50, 82, 1);
color: #fff;
}
width: 212px;
height: 80px;
background: rgba(1, 50, 82, 0.1);
border-radius: 40px;
font-size: 30px;
color: #333;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
}
}
}
.center{
width: 100vw;
padding: 24px;
box-sizing: border-box;
.centerBox{
width: 100%;
background: #044067;
border-radius: 20px;
box-sizing: border-box;
padding: 30px 28px;
>div{
color: #fff;
font-size: 30px;
text-align: center;
line-height: 80px;
}
}
}
}
效果展示