回到顶部按钮:滚动淡入 + 平滑滚动
- 滚动超过 300px 后按钮优雅淡入(translate-y + opacity 过渡) - 点击后平滑滚动到顶部(behavior: smooth) - 首页和积分榜页均添加 - 按钮隐藏时 pointer-events-none 防止误触 Co-Authored-By: new-provider/LongCat-2.0 <<EMAIL>> )
This commit is contained in:
@@ -195,6 +195,16 @@ export default function Matches() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [showAllUpcoming, setShowAllUpcoming] = useState(false) // 默认仅展示未来 3 天;true 展开全部
|
||||
const [liveMatches, setLiveMatches] = useState<Match[]>([]) // 进行中比赛(顶部独立区块)
|
||||
const [showBackTop, setShowBackTop] = useState(false) // 回到顶部按钮显示态
|
||||
|
||||
// 监听滚动,超过 300px 显示回到顶部按钮
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setShowBackTop(window.scrollY > 300)
|
||||
window.addEventListener('scroll', handleScroll, { passive: true })
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}, [])
|
||||
|
||||
const scrollToTop = () => window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
const [predictingId, setPredictingId] = useState<number | null>(null)
|
||||
const [prediction, setPrediction] = useState<Prediction | null>(null)
|
||||
const [predictionFor, setPredictionFor] = useState<Match | null>(null)
|
||||
@@ -682,6 +692,18 @@ export default function Matches() {
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* 回到顶部按钮 */}
|
||||
<button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-6 right-6 z-40 flex h-10 w-10 items-center justify-center rounded-full border border-ink-200 bg-paper-50 text-ink-600 shadow-lg transition-all duration-300 hover:border-ink-400 hover:text-ink-900 ${
|
||||
showBackTop ? 'translate-y-0 opacity-100' : 'translate-y-4 opacity-0 pointer-events-none'
|
||||
}`}
|
||||
aria-label="回到顶部"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5 15l7-7 7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user