链式代理段出现消失不再抖动

抖动有两个来源。主要的是 .block + .block 给的 24px 上外边距在高度折叠
动画之外,出现和消失的瞬间各跳一下,折叠钩子现在把 margin-top 和高度
一起做插值。次要的是整页高度跨过视口阈值时滚动条出现消失让内容横移,
用 scrollbar-gutter 把滚动条位置常驻留出来。
This commit is contained in:
2026-08-11 17:04:11 +08:00
parent 272a0931a1
commit 58d317afce
2 changed files with 16 additions and 4 deletions
+11 -4
View File
@@ -158,23 +158,29 @@ function lockHeight() {
}
/**
* v-if 内容的展开收起动画:高度在 0 和实际值之间过渡,结束后清掉内联样式。
* 给配置表单和链式代理段用。auto 高度不可插值,只能量出来做。
* v-if 内容的展开收起动画:高度和上外边距一起在 0 和实际值之间过渡,结束后清掉
* 内联样式。给配置表单和链式代理段用。auto 高度不可插值,只能量出来做。
* 外边距必须一起动:链式代理段顶着 .block + .block 给的 24px margin,它在高度
* 动画之外,不带上它出现和消失的瞬间就各抖一下。
*/
function foldEnter(element: Element, done: () => void) {
const el = element as HTMLElement
// 先量再压:此刻元素是自然高度,revealBottom 量到的就是折叠结束后的位置
revealBottom()
const margin = getComputedStyle(el).marginTop
el.style.height = '0'
el.style.marginTop = '0'
el.style.overflow = 'hidden'
void el.offsetHeight
el.style.transition = 'height 0.15s ease'
el.style.transition = 'height 0.15s ease, margin-top 0.15s ease'
el.style.height = `${String(el.scrollHeight)}px`
el.style.marginTop = margin
el.addEventListener(
'transitionend',
() => {
el.style.transition = ''
el.style.height = ''
el.style.marginTop = ''
el.style.overflow = ''
done()
},
@@ -187,8 +193,9 @@ function foldLeave(element: Element, done: () => void) {
el.style.height = `${String(el.offsetHeight)}px`
el.style.overflow = 'hidden'
void el.offsetHeight
el.style.transition = 'height 0.15s ease'
el.style.transition = 'height 0.15s ease, margin-top 0.15s ease'
el.style.height = '0'
el.style.marginTop = '0'
el.addEventListener('transitionend', done, { once: true })
}