Files
KatelyaTV/EPISODE_CLICK_DEEP_FIX.md
T

4.0 KiB
Raw Blame History

选集点击偏移问题的深度修复

问题复现

用户点击第 6 集(紫色框框),但系统选择了第 7 集(绿色填充),存在点击偏移问题。

深度分析与修复

🔍 问题根因分析

经过多轮调试,发现问题有多个层面

1. CSS Grid 布局问题

/* 问题代码 */
grid-cols-[repeat(auto-fill,minmax(40px,1fr))]

/* 问题分析 */
- minmax(40px,1fr) 中的 1fr 导致按钮宽度不固定
- 在不同屏幕宽度下按钮实际宽度变化很大
- 视觉按钮位置与点击区域不匹配

2. 事件处理逻辑问题

// 问题代码
const handleEpisodeChange = (episodeNumber: number) => {
  if (episodeNumber >= 0 && episodeNumber < totalEpisodes) {
    setCurrentEpisodeIndex(episodeNumber); // 错误!
  }
};

// 问题分析
- EpisodeSelector传递的是显示集数(1-based): 1, 2, 3, 4, 5, 6, 7...
- 但直接设置为currentEpisodeIndex(0-based): 0, 1, 2, 3, 4, 5, 6...
- 导致点击第6集实际设置为index=6对应第7集

3. 可能的覆盖层问题

  • SkipController 的固定定位面板可能覆盖选集区域
  • 已移动到左下角,但可能不彻底

🔧 完整修复方案

修复 1: CSS 布局优化

// 修复前
<div className='grid grid-cols-[repeat(auto-fill,minmax(40px,1fr))] auto-rows-[40px] gap-x-3 gap-y-3'>

// 修复后
<div className='grid grid-cols-[repeat(auto-fill,48px)] justify-center gap-3'>

效果

  • 每个按钮固定 48px 宽度
  • 使用 justify-center 居中对齐
  • 消除弹性宽度导致的位置偏移

修复 2: 事件处理修正

// 修复前
const handleEpisodeChange = (episodeNumber: number) => {
  if (episodeNumber >= 0 && episodeNumber < totalEpisodes) {
    setCurrentEpisodeIndex(episodeNumber); // 直接使用显示集数作为索引
  }
};

// 修复后
const handleEpisodeChange = (episodeNumber: number) => {
  const episodeIndex = episodeNumber - 1; // 转换:显示集数 -> 数组索引
  if (episodeIndex >= 0 && episodeIndex < totalEpisodes) {
    setCurrentEpisodeIndex(episodeIndex);
  }
};

效果

  • 正确处理集数显示值到数组索引的转换
  • 点击第 6 集 → episodeNumber=6 → episodeIndex=5 → 正确选择第 6 集

修复 3: 增强事件控制

// 添加更强的事件控制
onClick={(e) => {
  e.preventDefault();
  e.stopPropagation();
  handleEpisodeClick(episodeNumber);
}}

🎯 修复验证

数据流验证

  1. 用户点击第 6 集按钮
  2. EpisodeSelector.tsx: handleEpisodeClick(6)onChange(6)
  3. play/page.tsx: handleEpisodeChange(6)episodeIndex = 6-1 = 5
  4. 状态更新: setCurrentEpisodeIndex(5) → 选中第 6 集(index=5
  5. UI 更新: value={currentEpisodeIndex + 1} = 5+1 = 6 → 第 6 集高亮

布局验证

  • 固定 48px 宽度确保按钮大小一致
  • justify-center 确保居中对齐
  • gap-3 提供合适的间距

📁 修改文件

  1. src/components/EpisodeSelector.tsx

    • 修复 CSS Grid 布局:固定按钮宽度
    • 增强点击事件处理
  2. src/app/play/page.tsx

    • 修复 handleEpisodeChange 逻辑错误
    • 正确处理显示集数到索引的转换
  3. src/components/SkipController.tsx

    • 移动固定面板位置(之前已修复)

🚀 预期效果

修复后的行为:

  • 点击第 1 集 → 选择第 1 集
  • 点击第 6 集 → 选择第 6 集
  • 点击第 7 集 → 选择第 7 集
  • 按钮布局美观,宽度一致
  • 不受屏幕宽度影响

💡 经验总结

  1. UI 显示值 vs 数据索引:要区分用户看到的值(1-based)和内部索引(0-based)
  2. CSS 弹性布局:在需要精确点击的场景下,避免使用 1fr 等弹性单位
  3. 多层问题:复杂 bug 可能有多个层面的原因,需要逐层排查
  4. 事件处理:添加 preventDefault 和 stopPropagation 增强控制

这次修复解决了根本问题,确保点击精确性和用户体验。