Skip to content

Latest commit

 

History

History
85 lines (55 loc) · 4.19 KB

File metadata and controls

85 lines (55 loc) · 4.19 KB

移动端键盘弹出时 memo 列表塌陷

现象

iPhone 与 iPad 上打开 Quick Capture 侧边栏,点击输入框调出软键盘后,memo 列表消失,输入框下方到键盘之间是一整片空白。

根本原因

键盘弹出时,Obsidian 对内容区做了两次互相冲突的补偿:

  1. 把整个应用缩小,让 leaf 的底边正好停在键盘顶边(实测都是 502)
  2. 又给 .view-content 加上一段等于键盘高度的 padding-bottom(实测 iPhone 上是 372px),这是给「内容整体滚动」型视图准备的常规手段,防止内容被键盘挡住

第二条对我们是纯粹的伤害。Quick Capture 的根容器就是这个 .view-content,而且是一个固定高度的 flex 纵向容器,不整体滚动。于是:

  • 容器总高 388
  • 减去上内边距 12、下内边距 372
  • 真正能放内容的地方只剩 4px

.jp-pane-capture 在这种情况下算出 0 高度是完全正确的结果,里面本来就没有空间可分。列表随之塌陷。

修复

在移动端把这段内边距压掉,空间还给内容,其余布局按原有的 flex 规则自然成立,不需要任何 JS 参与。

.is-mobile .jp-capture-root {
  padding-bottom: 0 !important;
}
.is-mobile .jp-timeline-scroll {
  padding-bottom: 8px;
}

两点说明:

  • !important 是必需的,因为 Obsidian 把这段内边距写成了行内样式
  • 归零而不是恢复成面板原本的 12px。键盘占屏时每一点空间都值钱,列表贴着面板边缘是移动端的常态。底部的呼吸感改由列表自己的 8px 内边距提供,它在滚动区内部,滚到底才占位,不会平白留白

修复后实测,根容器、记录面板、memo 列表三者底边精确重合在 502,也就是键盘顶边。

排查过程中的关键数据

capture-view.ts 里临时加探针,用 Notice 把布局数值打到屏幕上,iPhone 实测(单位为 CSS px)。各元素高度变化:

元素 键盘弹出前 键盘弹出后
.jp-capture-root 根容器 760 388
.jp-tab-bar 标签栏 30 30
.jp-pane-capture 记录面板 666 0
.jp-capture-card 输入卡片 149 149
.jp-timeline-scroll 时间轴 505 140

决定性的一组,来自打印父链计算样式的那次探针:

^0 view-content.capture-root
   rect=388 disp=flex/column h=387.98px
   pad=12px/372px gap=12px ovf=auto

pad 的第二个值 372 就是答案。它等于键盘高度(874 − 502)。

走过的弯路

前后改了七八轮都没解决,因为一直在给症状打补丁,没有先查「面板为什么是 0」:

  1. 给时间轴加 min-height: 140px。列表能显示了,但值是写死的,跟实际空间对不上,底部留白
  2. 把面板改成 flex: 1 1 0。无效,面板仍是 0
  3. 用 JS 测量可用空间赋值给时间轴。每次算出的值都不大于 80,取了兜底值。当时误判成「测量时机太早」,加了延时补测,仍然无效。现在回头看,读到的数值是对的,是那 372px 内边距让可用空间本来就接近 0
  4. 期间还发现时间轴作为 flex 子元素会被收缩回去,需要配合 flex: none 才能让赋的高度生效

这些补丁在定位到真因后已全部删除。

教训是:现象出现在哪一层,原因不一定在那一层。应该先往上追问「这个数值凭什么是这样」,而不是直接去改这个数值。

另一个坑:CSS 注释写坏会静默吞掉规则

排查期间连续两次编辑同一段 CSS 注释,第二次插入的文字落在了前一个 */ 后面,变成注释外的游离文本。CSS 解析器会连带吞掉紧跟其后的整条规则,表现出来是「改了没有任何效果」,一度让排查方向跑偏。

改完 CSS 应当检查注释配对与花括号配平,不要只靠肉眼。

相关改动

问题由 a0a241e「固定输入框与日期头,仅 memo 列表可滚动」暴露。那次把 .jp-capture-rootoverflow-y: auto 改成 overflow: hidden,滚动权交给 .jp-timeline-scroll。改之前整个侧边栏可以整体滚动,空间不够时内容只是溢出,往下滑还能看到 memo,所以那 372px 内边距造成的挤压不可见。