From f6c2ccf0cce55214a93e2755eeb93633b4f63098 Mon Sep 17 00:00:00 2001 From: LooseLi <1329307562@qq.com> Date: Tue, 15 Apr 2025 14:45:58 +0800 Subject: [PATCH] fix: correct RightFloatArea hiding behavior when scrolling back to top --- themes/hexo/components/RightFloatArea.js | 56 +++++++++++++++--------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/themes/hexo/components/RightFloatArea.js b/themes/hexo/components/RightFloatArea.js index 162081b2..1facb110 100644 --- a/themes/hexo/components/RightFloatArea.js +++ b/themes/hexo/components/RightFloatArea.js @@ -1,36 +1,52 @@ -import throttle from 'lodash.throttle' import { useCallback, useEffect, useState } from 'react' import ButtonDarkModeFloat from './ButtonFloatDarkMode' import ButtonJumpToTop from './ButtonJumpToTop' /** * 悬浮在右下角的按钮,当页面向下滚动100px时会出现 + * 当页面回到顶部时会隐藏 * @param {*} param0 * @returns */ export default function RightFloatArea({ floatSlot }) { const [showFloatButton, switchShow] = useState(false) - const scrollListener = useCallback( - throttle(() => { - const targetRef = document.getElementById('wrapper') - const clientHeight = targetRef?.clientHeight - const scrollY = window.pageYOffset - const fullHeight = clientHeight - window.outerHeight - let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0)) - if (per > 100) per = 100 - const shouldShow = scrollY > 100 && per > 0 - // 右下角显示悬浮按钮 - if (shouldShow !== showFloatButton) { - switchShow(shouldShow) - } - }, 200) - ) + const scrollListener = useCallback(() => { + const targetRef = document.getElementById('wrapper') || document.documentElement + const clientHeight = targetRef?.clientHeight || 0 + const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0 + const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0 + + const fullHeight = Math.max(1, clientHeight - viewportHeight) + + let per = parseFloat(((scrollY / fullHeight) * 100).toFixed(0)) + + // 完整的边界处理 + if (isNaN(per) || per < 0) per = 0 + if (per > 100) per = 100 + + const shouldShow = scrollY > 100 && per > 0 + + // 右下角显示悬浮按钮 + if (shouldShow !== showFloatButton) { + switchShow(shouldShow) + } + }, [showFloatButton]) useEffect(() => { - document.addEventListener('scroll', scrollListener) - return () => document.removeEventListener('scroll', scrollListener) - }, []) + const throttledScroll = () => { + window.requestAnimationFrame(() => { + scrollListener() + }) + } + + window.addEventListener('scroll', throttledScroll) + + // 初始调用一次检查初始状态 + scrollListener() + + return () => window.removeEventListener('scroll', throttledScroll) + }, [scrollListener]) return (