mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-05-18 03:37:28 +08:00
feat: add back to top buttom
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps, @typescript-eslint/no-explicit-any */
|
/* eslint-disable react-hooks/exhaustive-deps, @typescript-eslint/no-explicit-any */
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Search, X } from 'lucide-react';
|
import { ChevronUp, Search, X } from 'lucide-react';
|
||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import { Suspense, useEffect, useMemo, useState } from 'react';
|
import { Suspense, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
@@ -20,6 +20,8 @@ import VideoCard from '@/components/VideoCard';
|
|||||||
function SearchPageClient() {
|
function SearchPageClient() {
|
||||||
// 搜索历史
|
// 搜索历史
|
||||||
const [searchHistory, setSearchHistory] = useState<string[]>([]);
|
const [searchHistory, setSearchHistory] = useState<string[]>([]);
|
||||||
|
// 返回顶部按钮显示状态
|
||||||
|
const [showBackToTop, setShowBackToTop] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
@@ -104,7 +106,42 @@ function SearchPageClient() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return unsubscribe;
|
// 获取滚动位置的函数 - 专门针对 body 滚动
|
||||||
|
const getScrollTop = () => {
|
||||||
|
return document.body.scrollTop || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用 requestAnimationFrame 持续检测滚动位置
|
||||||
|
let isRunning = false;
|
||||||
|
const checkScrollPosition = () => {
|
||||||
|
if (!isRunning) return;
|
||||||
|
|
||||||
|
const scrollTop = getScrollTop();
|
||||||
|
const shouldShow = scrollTop > 300;
|
||||||
|
setShowBackToTop(shouldShow);
|
||||||
|
|
||||||
|
requestAnimationFrame(checkScrollPosition);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动持续检测
|
||||||
|
isRunning = true;
|
||||||
|
checkScrollPosition();
|
||||||
|
|
||||||
|
// 监听 body 元素的滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
const scrollTop = getScrollTop();
|
||||||
|
setShowBackToTop(scrollTop > 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsubscribe();
|
||||||
|
isRunning = false; // 停止 requestAnimationFrame 循环
|
||||||
|
|
||||||
|
// 移除 body 滚动事件监听器
|
||||||
|
document.body.removeEventListener('scroll', handleScroll);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -181,6 +218,20 @@ function SearchPageClient() {
|
|||||||
addSearchHistory(trimmed);
|
addSearchHistory(trimmed);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 返回顶部功能
|
||||||
|
const scrollToTop = () => {
|
||||||
|
try {
|
||||||
|
// 根据调试结果,真正的滚动容器是 document.body
|
||||||
|
document.body.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// 如果平滑滚动完全失败,使用立即滚动
|
||||||
|
document.body.scrollTop = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout activePath='/search'>
|
<PageLayout activePath='/search'>
|
||||||
<div className='px-4 sm:px-10 py-4 sm:py-8 overflow-visible mb-10'>
|
<div className='px-4 sm:px-10 py-4 sm:py-8 overflow-visible mb-10'>
|
||||||
@@ -333,6 +384,19 @@ function SearchPageClient() {
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 返回顶部悬浮按钮 */}
|
||||||
|
<button
|
||||||
|
onClick={scrollToTop}
|
||||||
|
className={`fixed bottom-20 md:bottom-6 right-6 z-[500] w-12 h-12 bg-green-500/90 hover:bg-green-500 text-white rounded-full shadow-lg backdrop-blur-sm transition-all duration-300 ease-in-out flex items-center justify-center group ${
|
||||||
|
showBackToTop
|
||||||
|
? 'opacity-100 translate-y-0 pointer-events-auto'
|
||||||
|
: 'opacity-0 translate-y-4 pointer-events-none'
|
||||||
|
}`}
|
||||||
|
aria-label='返回顶部'
|
||||||
|
>
|
||||||
|
<ChevronUp className='w-6 h-6 transition-transform group-hover:scale-110' />
|
||||||
|
</button>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user