修复: 虚拟滚动 IO 卸载分支 height=0 时 minHeight fallback 防 slot 塌 0 重叠(P0)
This commit is contained in:
@@ -69,9 +69,14 @@ export function useAiVirtualScroll(options: AiVirtualScrollOptions) {
|
||||
// 卸载前:把实测高度锁到 sentinel 的 minHeight,防内容移除后 sentinel 塌成 0
|
||||
// → scrollHeight 不变 → isNearBottom/scrollToBottom/回到底部计算零感知。
|
||||
// 内容重新挂载时 RO 会把真实高度回填,registerSentinel 复挂时清 minHeight 由真实高度接管。
|
||||
// 防御(P0):RO 首次回调前 item 已被 IO 判不可见时 meta.height===0,直接不设 minHeight
|
||||
// → sentinel 塌 0 高 → 下条消息上浮重叠。此处兜底:height>0 用实测值,
|
||||
// height===0 用 el.offsetWidth 量得的实际渲染高度(此时 el 仍在 DOM),仍<=0 则用固定 40px。
|
||||
const meta = itemMeta.get(key)
|
||||
if (meta && meta.height > 0 && meta.el.isConnected) {
|
||||
meta.el.style.minHeight = `${meta.height}px`
|
||||
if (meta && meta.el.isConnected) {
|
||||
const measured = meta.height > 0 ? meta.height : (meta.el.offsetHeight || 0)
|
||||
const placeholder = measured > 0 ? measured : 40
|
||||
meta.el.style.minHeight = `${placeholder}px`
|
||||
}
|
||||
next.delete(key); changed = true
|
||||
}
|
||||
@@ -98,9 +103,12 @@ export function useAiVirtualScroll(options: AiVirtualScrollOptions) {
|
||||
const prev = itemMeta.get(key)
|
||||
if (el instanceof HTMLElement) {
|
||||
el.dataset.vscrollKey = key
|
||||
// 复用上次实测高度作为初始 inline 占位(再次挂载时先占位,内容挂载后 RO 再校准)
|
||||
// 复用上次实测高度作为初始 inline 占位(再次挂载时先占位,内容挂载后 RO 再校准)。
|
||||
// 防御(P0):首次挂载(无 prev / RO 未回填)h<=0 时若不设占位,sentinel 首帧塌 0 高 →
|
||||
// 列表首次渲染时下条上浮重叠。此处用保守默认 40px 占位,RO 回调后用真实高度覆盖。
|
||||
const h = prev?.height ?? 0
|
||||
if (h > 0) el.style.minHeight = `${h}px`
|
||||
const placeholder = h > 0 ? h : 40
|
||||
el.style.minHeight = `${placeholder}px`
|
||||
itemMeta.set(key, { el, height: h })
|
||||
ensureObserver()
|
||||
io?.observe(el)
|
||||
|
||||
Reference in New Issue
Block a user