← 全部日志

聊天「就地往下展开」+ 回答渲染 Markdown:三版才丝滑

2026-06-17约 2.5 小时体验聊天重构踩坑

目标

两个体验欠账:①三个聊天入口(hero 胶囊 / 导航胶囊 / 速览第七卡)都是 href="#twin" 锚点,点了直接跳到底部终章、跳过中间六屏正文;②分身回答常带 Markdown(**加粗**- 列表),气泡却是纯文本、符号原样露。

三版迭代(值得记的全是被否的过程)

  1. 居中弹窗浮层——站主一句否:「就在这展开对话框,不是弹窗」。记下:「不跳转」≠「弹窗」。
  2. 退出剧场 + 滚到顶就地展开——点击即把首页退出 scrub 剧场、scrollTo(0)、藏掉 hero 大字、对话框在 hero 中央展开。站主再否:「乱跳」。根因:从 scrub 中途位置点击 → scrollTo(0) 一大跳 + 退出剧场使页面高度骤变 + display:none 重排,三重跳动。
  3. 就地往下长出(最终)不碰剧场、不滚动、不重排——在被点元素位置 fixed 锚一张深色聊天卡,clip-path: inset(... 100% ...) → inset(0) 自上而下「长出来」(不挤压文字),打开时锁滚动把页面冻在原地。于是零跳动、丝滑。横向居中(胶囊本就居中=从胶囊处长出)、竖向从被点元素顶部往下、底部不溢出才上钳;透明点击区点外关闭,无遮罩压暗(页面照常可见,不是弹窗)。

结果

  • 全局 ChatExpander(挂 layout,按 pathname 选中英):capture 阶段拦 [data-chat-entry] 点击 → 记录被点元素 rect → 锚定长出。ChatPanel 懒加载;终章真窗聊天岛保留作无 JS 兜底(入口 href="#twin" 无 JS 时照常跳终章)。
  • Markdown 渲染ChatMarkdown 复用 react-markdown + remark-gfm(零新依赖),prose-invert 渲染回答。

踩坑与纠正

  • 聊天卡在白底 hero 上看不见ChatPanel 是为终章黑底做的深色主题(bg-white/[0.06]、白字白按钮),搬到白底上几乎全隐形。改实色 bg-[#1c1c1e]:白底上是清晰深色卡,黑底终章上是浮起卡,两处都对。
  • 又踩 RSC 边界:客户端组件别收整个 content(含 getProject 函数,next build 预渲染会炸),只传可序列化字段。
  • clip-path 揭示而非 scaleY:用 scaleY 长出会把文字竖向挤压抖动;改 clip-path 自上而下揭示,文字不变形、真正「长出来」。

用时与备注

约 2.5 小时(含两版被否 + 重做)。lint/typecheck/build 全绿、49 页。生产构建实测:点击入口就地长出居中深色卡、页面 scrollY 不变(零跳动)、剧场不被打断;演示兜底 - 列表渲染成真列表。本批未部署(站主计划重购域名后再上线)。