feat: 实现纵向模式和平铺模式的双向无限滚动
问题描述:
- 纵向模式下,用户向上滑动触发懒加载后,向下滑动无法回到之前的内容
- 原因:纵向模式未启用累积模式,且缺少向上滚动加载上一页的功能
解决方案:
实现类似社交媒体的双向无限滚动机制:
- 向下滚动到 60% 时自动加载下一页(新内容)
- 向上滚动到顶部 10% 时自动加载上一页(旧内容)
- 加载上一页后自动调整滚动位置,保持用户视图不跳动
技术实现:
1. usePagination.js
- 将 VERTICAL 模式加入累积模式判断 (line 57)
- 实现 loadPrevPage 方法,支持加载上一页 (lines 285-306)
- 导出 loadPrevPage 供组件使用 (line 364)
2. VirtualizedFourRowGrid.js
- 添加 loadPrevPage prop 和 previousScrollHeight ref
- 合并双向滚动检测逻辑 (lines 67-102):
* 向下滚动: scrollPercentage > 0.6 触发 loadNextPage
* 向上滚动: scrollTop < clientHeight * 0.1 触发 loadPrevPage
- 实现滚动位置保持机制 (lines 133-161):
* 记录加载前的 scrollHeight
* 加载完成后计算高度差
* 调整 scrollTop += heightDifference 保持视图位置
3. DynamicNewsCard.js
- 从 usePagination 获取 loadPrevPage
- 传递给 EventScrollList 组件
4. EventScrollList.js
- 接收并传递 loadPrevPage 到 VirtualizedFourRowGrid
- 四排模式和纵向模式均支持双向滚动
影响范围:
- 纵向模式 (vertical mode)
- 平铺模式 (four-row mode)
测试建议:
1. 切换到纵向模式
2. 向下滚动观察是否自动加载下一页
3. 向上滚动到顶部观察是否:
- 自动加载上一页
- 滚动位置保持不变,内容不跳动
4. 切换到平铺模式验证双向滚动同样生效
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,7 @@ const EventScrollList = ({
|
||||
displayEvents, // 累积显示的事件列表(四排模式用)
|
||||
isAccumulateMode, // 是否累积模式
|
||||
loadNextPage, // 加载下一页(无限滚动)
|
||||
loadPrevPage, // 加载上一页(双向无限滚动)
|
||||
onFourRowEventClick, // 四排模式事件点击回调(打开弹窗)
|
||||
selectedEvent,
|
||||
onEventSelect,
|
||||
@@ -270,7 +271,7 @@ const EventScrollList = ({
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{/* 模式3: 四排网格模式 - 使用虚拟滚动 + 无限滚动 */}
|
||||
{/* 模式3: 四排网格模式 - 使用虚拟滚动 + 双向无限滚动 */}
|
||||
{mode === 'four-row' && (
|
||||
<VirtualizedFourRowGrid
|
||||
events={displayEvents || events} // 使用累积列表(如果有)
|
||||
@@ -281,6 +282,7 @@ const EventScrollList = ({
|
||||
getTimelineBoxStyle={getTimelineBoxStyle}
|
||||
borderColor={borderColor}
|
||||
loadNextPage={loadNextPage} // 加载下一页
|
||||
loadPrevPage={loadPrevPage} // 加载上一页(双向滚动)
|
||||
hasMore={hasMore} // 是否还有更多数据
|
||||
loading={loading} // 加载状态
|
||||
/>
|
||||
@@ -289,7 +291,7 @@ const EventScrollList = ({
|
||||
{/* 模式4: 纵向分栏模式 - 横向布局(时间在左,卡片在右) */}
|
||||
{mode === 'vertical' && (
|
||||
<Grid templateColumns="1fr 2fr" gap={6} minH="500px" maxH="800px">
|
||||
{/* 左侧:事件列表 (33.3%) - 使用虚拟滚动 + 无限滚动 */}
|
||||
{/* 左侧:事件列表 (33.3%) - 使用虚拟滚动 + 双向无限滚动 */}
|
||||
<GridItem>
|
||||
<VirtualizedFourRowGrid
|
||||
events={displayEvents || events} // 使用累积列表
|
||||
@@ -301,7 +303,8 @@ const EventScrollList = ({
|
||||
onToggleFollow={onToggleFollow}
|
||||
getTimelineBoxStyle={getTimelineBoxStyle}
|
||||
borderColor={borderColor}
|
||||
loadNextPage={loadNextPage} // 支持无限滚动
|
||||
loadNextPage={loadNextPage} // 支持向下无限滚动
|
||||
loadPrevPage={loadPrevPage} // 支持向上无限滚动(双向滚动)
|
||||
hasMore={hasMore}
|
||||
loading={loading}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user