--- name: chat_block_scroll_anchor description: 当需要优化聊天区域块展开/折叠滚动行为,或排查向上滚动后瞬间跳回问题时,应该索引本记忆 --- # 聊天区域块展开/折叠滚动行为优化记录 ## 背景 聊天区域默认使用 `vue-stick-to-bottom` 保持底部锁定。块(thinking/tool)展开/折叠时,`stick-to-bottom` 的弹簧追底动画和 CSS 高度过渡不同步,会产生「向下展开一点、向上滚动一点」的顿挫感。 ## 已尝试方案 ### 1. 块展开锚定(useBlockExpansionAnchor) - 在 `static/src/composables/useBlockExpansionAnchor.ts` 中实现 - 块展开/折叠的 CSS 过渡期间(约 260–300ms),用 `requestAnimationFrame` 持续覆盖 `scrollTop` - 目标:让被操作块的底边或顶边保持在原来视口位置 - 方向判断: - 用**底边**判断比顶边更准确。高块即使顶边位于上半,底边仍可能在下半;用顶边判断会把高块误判为 `down` 模式 - `up` 模式:底边不动,头部向上展开 - `down` 模式:顶边不动,内容向下展开 - 方向在单次展开-收起周期内记忆(`preferredModes`),保证收起是展开的倒放;收起动画结束后清除记录 ### 2. 运行期间策略 - 运行中的 thinking/tool 块(带 `.processing`/`.running`/`.thinking-animation`)保持旧逻辑,由 `stick-to-bottom` 追底,避免被输入栏遮挡 - 非运行中的块(包括运行期间的历史块)走锚定逻辑 - 已实现 commit:`f43b5ea7 fix(chat): 运行期间恢复旧滚动逻辑,堆叠块更多按钮也接入锚定` ### 3. 堆叠块「更多」按钮 - `StackedBlocks.vue` 在 toggleMore 时 emit `more-toggle`,`ChatArea.vue` 监听后对 more-block 元素启动锚定 - 注意:事件 payload 里的展开状态应使用 `payload.expanded`,避免 `ReferenceError` ## 未解决的向上滚动跳回问题 ### 现象 - 在块较多的对话中,**向上滚动**后页面会瞬间跳回滚动前的位置 - 向下滚动不会出现 - 禁用 `anchorBlockElement` 调用、禁用 wheel-up 时的 `stopScroll()` 后问题依然存在 ### 调试结论 - 不是 `anchorBlockElement` 直接导致 - 不是 `stopScroll()` 直接导致 - `heightDelta` 可能为负(内容高度减小),但 large-growth 检测未触发 - `escapedFromLock` 已为 `true`,`stick-state-change` 未出现异常变化 - 原因未最终定位,可能与 `vue-stick-to-bottom` 内部状态、浏览器原生滚动行为或内容高度变化后的布局抖动有关 ## 当前代码状态 - 当前 HEAD:`f43b5ea7 fix(chat): 运行期间恢复旧滚动逻辑,堆叠块更多按钮也接入锚定` - 工作区干净,所有调试和临时修改已撤回,stash 已清空 - 后续若继续优化,建议从 `f43b5ea7` 开始,并优先定位向上滚动跳回的根本原因