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