feat: support episode selector scroll

This commit is contained in:
shinya
2025-08-26 00:15:57 +08:00
parent 5472777d3a
commit 446695d79c

View File

@@ -173,7 +173,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
}
}, [precomputedVideoInfo]);
// 读取本地优选和测速开关,默认开启
// 读取本地"优选和测速"开关,默认开启
const [optimizationEnabled] = useState<boolean>(() => {
if (typeof window !== 'undefined') {
const saved = localStorage.getItem('enableOptimization');
@@ -241,6 +241,50 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
const categoryContainerRef = useRef<HTMLDivElement>(null);
const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);
// 添加鼠标悬停状态管理
const [isCategoryHovered, setIsCategoryHovered] = useState(false);
// 阻止页面竖向滚动
const preventPageScroll = useCallback((e: WheelEvent) => {
if (isCategoryHovered) {
e.preventDefault();
}
}, [isCategoryHovered]);
// 处理滚轮事件,实现横向滚动
const handleWheel = useCallback((e: WheelEvent) => {
if (isCategoryHovered && categoryContainerRef.current) {
e.preventDefault(); // 阻止默认的竖向滚动
const container = categoryContainerRef.current;
const scrollAmount = e.deltaY * 2; // 调整滚动速度
// 根据滚轮方向进行横向滚动
container.scrollBy({
left: scrollAmount,
behavior: 'smooth'
});
}
}, [isCategoryHovered]);
// 添加全局wheel事件监听器
useEffect(() => {
if (isCategoryHovered) {
// 鼠标悬停时阻止页面滚动
document.addEventListener('wheel', preventPageScroll, { passive: false });
document.addEventListener('wheel', handleWheel, { passive: false });
} else {
// 鼠标离开时恢复页面滚动
document.removeEventListener('wheel', preventPageScroll);
document.removeEventListener('wheel', handleWheel);
}
return () => {
document.removeEventListener('wheel', preventPageScroll);
document.removeEventListener('wheel', handleWheel);
};
}, [isCategoryHovered, preventPageScroll, handleWheel]);
// 当分页切换时,将激活的分页标签滚动到视口中间
useEffect(() => {
const btn = buttonRefs.current[displayPage];
@@ -339,7 +383,12 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
<>
{/* 分类标签 */}
<div className='flex items-center gap-4 mb-4 border-b border-gray-300 dark:border-gray-700 -mx-6 px-6 flex-shrink-0'>
<div className='flex-1 overflow-x-auto' ref={categoryContainerRef}>
<div
className='flex-1 overflow-x-auto'
ref={categoryContainerRef}
onMouseEnter={() => setIsCategoryHovered(true)}
onMouseLeave={() => setIsCategoryHovered(false)}
>
<div className='flex gap-2 min-w-max'>
{categories.map((label, idx) => {
const isActive = idx === displayPage;