<!-- 我原有的Home3.0逻辑 爬楼层效果 -->
const [blockTop, setBlockTop] = useState<{ top: number; bgMode: string }[]>(
[],
);
const getBannerHeight = () => {
const banner = document.getElementById('banner');
const appbar = document.getElementById('appbar');
if (banner && appbar) {
const bannerTop = getElementTop(banner);
const bannerHeight = banner.clientHeight;
return bannerTop + bannerHeight - appbar.offsetHeight;
}
return 0;
};
// 只获取了首页 top和bg
const getBlockTop = () => {
const blockEle = document.getElementById('home_wrap')?.childNodes || [];
return Array.from(blockEle)?.map(item => {
const bgMode =
window.getComputedStyle(item, null)?.backgroundColor ||
item.currentStyle.background;
const top = item.offsetTop;
return { bgMode: bgMode.includes('255') ? 'light' : 'dark', top };
});
};
// chang appbarState
const changAppbarState = (blockTopList, top) => {
for (let i = 0; i < blockTopList.length - 1; i++) {
if (blockTopList[i].top <= top && top < blockTopList[i + 1].top) {
if (blockTopList[i].bgMode === 'light') {
setAppbarState('light');
} else {
setAppbarState('dark');
}
}
if (top > blockTopList[blockTop.length - 1].top) {
if (blockTopList[blockTop.length - 1].bgMode === 'light') {
setAppbarState('light');
} else {
setAppbarState('dark');
}
}
}
};
const scrollEventHome = throttle(() => {
const top = getDocumentScrollTop();
if (Object.keys(blockTop).length) {
changAppbarState(blockTop, top);
}
// 粘性消失隐藏
if (Anchor.isAffix()) {
if (prevTop < 0) {
!Anchor.stop && setHidden(true);
}
if (prevTop >= 0 && prevTop < top) {
!Anchor.stop && setHidden(true);
}
}
// 上滑下滑消失隐藏
if (prevTop >= 0 && prevTop - top > 10) {
!Anchor.stop && setHidden(false);
}
if (prevTop >= 0 && prevTop - top < -10) {
!Anchor.stop && setHidden(true);
}
prevTop = top;
}, 300);
const scrollEventOther = throttle(() => {
const top = getDocumentScrollTop();
const banner = document.getElementById('banner');
const bannerHeight = getBannerHeight();
if (banner) {
if (top > 0) {
if (top > bannerHeight) {
setAppbarState('light');
} else {
setAppbarState('dark');
}
} else {
setAppbarState('dark');
}
}
if (Anchor.isAffix()) {
if (prevTop < 0) {
!Anchor.stop && setHidden(true);
}
if (prevTop >= 0 && prevTop < top) {
!Anchor.stop && setHidden(true);
}
}
if (prevTop >= 0 && prevTop > top) {
!Anchor.stop && setHidden(false);
}
prevTop = top;
}, 200);
useEffect(() => {
if (pathName === '/' && !Object.keys(blockTop).length) {
setBlockTop(getBlockTop());
return;
} else if (pathName === '/' && Object.keys(blockTop).length) {
APP_BAR_SCROLL_EVENT = scrollEventHome;
} else {
APP_BAR_SCROLL_EVENT = scrollEventOther;
}
canUseDom && window.addEventListener('scroll', APP_BAR_SCROLL_EVENT, false);
setTimeout(() => {
APP_BAR_SCROLL_EVENT();
}, 0);
setTimeout(() => {
if (document.documentElement.scrollTop !== 0) {
scrollTo(Math.max(0, document.documentElement.scrollTop + 1));
}
}, 10);
// eslint-disable-next-line consistent-return
return function clearUp() {
canUseDom && window.removeEventListener('scroll', APP_BAR_SCROLL_EVENT);
};
}, [blockTop]);
react 实现爬楼层效果
最新推荐文章于 2023-07-26 20:29:53 发布
本文详细介绍了如何在React应用中实现基于页面滚动的动态顶部栏(appbar)效果。通过监听滚动事件,计算不同区块的位置,动态调整appbar的样式和隐藏状态,同时涉及到元素定位、粘性定位以及页面不同区域的交互处理。内容涵盖了状态管理、性能优化(节流函数)和DOM操作等关键点。
摘要由CSDN通过智能技术生成