mole404
db05433596
feat(细节三): 确认框动画与背景位移、主菜单防误触高亮、头像阻塞加载、弹窗滚动链
① 三个(实为四个)sweetalert2 确认框(设置权限/重命名/删除/删相册):保留原实现,只改动画 +
斩断它对 body 的动手脚。四处 Swal.fire 加 heightAuto:false + scrollbarPadding:false;
common.less 里把 .swal2-show/.swal2-hide 换成与 x-modal 同一套(桌面 300ms ease-out 淡入+
scale .95→1、200ms ease-in 淡出;<768px 换成 translateY(16px)),遮罩过渡同源,并用
html body.swal2-shown:not(...) 兑掉 sweetalert2 对 body 的 overflow/padding 注入(不用 !important)。
实测:修前 4 个弹窗×2 视口都会让整页位移(桌面滚动条消失 +8px、手机注入 padding-right 8px 且
文档高 +20px、工具栏换行下移);修后逐项相等(关闭后复原也逐项相等)。动画实测 opacity 落在与
x-modal 同一条贝塞尔曲线上(如 ct=100/300 实测 0.6853 vs 曲线 0.6851,线性应为 0.3333)。
② 长按主菜单防误触高亮:把二级菜单那套手势级 arming 复用过来(menu-arming,420ms + 抬手后 260ms,
跟手势走),只在「这一发菜单确实紧随一次触摸」时武装,桌面右键路径一行都不走。
CDP 真触摸实测(390x844、iPhone UA、手指压在菜单项上):修前 elementFromPoint 命中 <a>(会高亮,
钉住粘滞 :hover 后整行变蓝 = 老师截图那个现象);修后按住期间/抬手+60ms 命中的都是外层容器、
不跳色,抬手+480ms 恢复正常可点;冗余窗内真点「复制图片」仍触发、点「复制链接」仍就地展开子菜单、
桌面鼠标 hover/点击行为与改前逐项一致。
③ 右上角头像:真因查明 —— 它是外部服务 https://cravatar.cn/avatar/<md5(email)>?s=96&d=mp&r=g
(Utils::getAvatar),实测 376B、0.85~0.96s、每次 1 跳重定向,且页面 load 事件被它拖住(实测
慢源下 load 3214ms)、加载失败时没有任何兜底(所以空着)。改法:先渲染固定 28×28 占位(不抖动),
真实地址放 data-avatar-src,页面 load 之后再异步接上;加 decoding=async + onerror 失败兜底
(名字首字色块圆圈)、成功则移除首字占位。实测:慢源下 load 3214ms → 470ms(不再等它),
404 时从"空白"变成"首字圆圈",且头像块与整个按钮的位置尺寸与修前逐项相等。
④ 手机在弹窗内下滑底部空一块:真因是**滚动链**——弹窗内滚到尽头后滚动传给背后文档(实测修前
document.scrollTop 从 0 冲到 2628),安卓上地址栏随之收起、底部露出空带。修法:弹窗滚动容器加
overscroll-contain 阻断接力;高度链上残留的 100vh 换成「同一块内先 vh 后 dvh」的内联声明
(CSSOM 实测 min-height 解析为 100dvh,祖先链已无 vh)。实测:修后 6 组手势(手机/桌面 × 长/短
内容 × wheel/touch)背后文档 scrollTop 恒为 0,弹窗内仍能正常滚到 maxScroll;桌面各项与改前逐项一致。
验证:longpress 79/79、sidebar 6/6、images-modal 35/35、images-modal-dom 35/35、swal-theme 48/48;
webpack compiled successfully;补丁钉住值同步为 context-js.js 3614ec17…、images.blade.php 09ba35f3…,
补丁重生成 2802 行且「打回上游 = 仓库文件」字节一致。另清理了子代理遗留的调试脚本 test/dbg-gap.mjs。