自动滚动改为折叠进场时预量最终高度;侧栏导航按钮间距加大

原来在 nextTick 量高度,此时折叠动画刚从 0 起步,配置展开量到 0 不滚,
链式代理量到半截滚一半。enter 钩子触发时元素刚插入、还是自然高度,
在把高度压到 0 之前先量,得到的就是折叠结束后的位置,滚动和折叠同时
开跑。触发点也从开关挪进 foldEnter,两个包装函数随之删掉。
This commit is contained in:
2026-08-11 16:51:49 +08:00
parent 0ddefd0d5d
commit d41012a0ab
2 changed files with 11 additions and 17 deletions
+10 -16
View File
@@ -132,22 +132,19 @@ const open = ref(false)
const rootEl = ref<HTMLElement | null>(null)
/**
* 展开配置或拨开链式代理后,详情底部可能长到窗口外,把新出现的内容滚进视野。
* 只挂在这两个动作上:tab 切换也会变高度,但来回切 tab 时页面跟着跳只会晕。
* 详情底部长出窗口外时,把新内容滚进视野。必须在 foldEnter 把高度压到 0 之前调:
* 那一刻元素刚插入、还是自然高度,量到的 bottom 就是折叠结束后的最终位置,
* 滚动因此能和折叠同时开跑、停在正确的地方;动画中途量到的只有半截。
* 只由配置展开和链式代理拨开触发(见 foldEnter):tab 切换也变高度,但不滚,
* 来回切 tab 时页面跟着跳只会晕。
*/
async function revealBottom() {
await nextTick()
function revealBottom() {
const el = rootEl.value
if (!el) return
const gap = el.getBoundingClientRect().bottom + 16 - window.innerHeight
if (gap > 0) window.scrollBy({ top: gap, behavior: 'smooth' })
}
function toggleOpen() {
open.value = !open.value
if (open.value) void revealBottom()
}
/**
* 切换选中的入站时,内容淡出淡入,容器高度从旧值滑到新值。
* 高度过渡没法纯 CSS 做:auto 不可插值。所以离开前把当前高度钉住,
@@ -166,6 +163,8 @@ function lockHeight() {
*/
function foldEnter(element: Element, done: () => void) {
const el = element as HTMLElement
// 先量再压:此刻元素是自然高度,revealBottom 量到的就是折叠结束后的位置
revealBottom()
el.style.height = '0'
el.style.overflow = 'hidden'
void el.offsetHeight
@@ -253,11 +252,6 @@ const chainOn = computed({
},
})
function toggleChain() {
chainOn.value = !chainOn.value
if (chainOn.value) void revealBottom()
}
// ── 草稿预览 ────────────────────────────────────────────
// 上半部分的显示规则只有一条:草稿和已保存一致时显示现实;不一致时显示「按草稿保存后
// 的样子」。点击的语义看卡片本身:现在就存在的成员任何时候点了都立刻生效,只有保存后
@@ -590,7 +584,7 @@ const complete = computed(
</section>
<section v-if="!panel.shared" class="block setup">
<button type="button" class="toggle" @click="toggleOpen">
<button type="button" class="toggle" @click="open = !open">
<span>配置</span>
<IconRight :class="['chev', open && 'is-open']" />
</button>
@@ -627,7 +621,7 @@ const complete = computed(
role="switch"
:aria-checked="chainOn"
:class="['switch', chainOn && 'is-on']"
@click="toggleChain"
@click="chainOn = !chainOn"
>
<span class="knob"></span>
</button>