2026-04-18-19-37-56 - 追加经验记录33:四项编辑器体验优化

This commit is contained in:
Administrator
2026-04-18 19:43:14 +08:00
parent f98177938f
commit 9c09e6cccc

View File

@@ -1001,3 +1001,49 @@ if ((settings.autoInsertDelay || 0) > 0) {
- 填充时是否正确读取并应用这些限制值 - 填充时是否正确读取并应用这些限制值
- 所有填充入口(本地上传、签名插入、系统素材、自动帧插入、拖拽填充)是否同步更新 - 所有填充入口(本地上传、签名插入、系统素材、自动帧插入、拖拽填充)是否同步更新
- 默认模板中的占位符如果没有 `max-width`/`max-height`,回退逻辑 `|| placeholder.style.width` 仍能正确获取限制值,但后续修改默认模板时应注意统一添加 `max-width`/`max-height` 以显式声明意图。 - 默认模板中的占位符如果没有 `max-width`/`max-height`,回退逻辑 `|| placeholder.style.width` 仍能正确获取限制值,但后续修改默认模板时应注意统一添加 `max-width`/`max-height` 以显式声明意图。
---
## 记录 33四项编辑器体验优化集中实施
**A. 具体问题**
1. 视频分析面板中「上传视频」按钮位于视频缩略图列表首位,不符合「先列出现有项,最后提供添加操作」的操作直觉。
2. 图片占位符内的提示文字未在框中绝对居中,当占位符高度较大时文字明显偏上。
3. 删除占位符内已插入的图片后,占位符保持收缩后的 `width:auto; height:auto` 尺寸,未恢复为原始预设大小。
4. 点击「左对齐/居中/右对齐」按钮时,浏览器原生 `execCommand('justifyLeft')` 会用 `<div align="left">` 包裹选区,导致包含 `.field-value` 或 `.image-placeholder` 的段落被肢解,文字与输入框/图片强制换行分离。
**B. 产生问题原因**
1. 上一轮重构视频面板时,将上传按钮移入了缩略图列表,但放在了首位而非末尾。
2. 占位符提示文字使用默认的行内流布局居中,依赖于 `line-height` 和父容器的 `align-items: center`,在填充后 `line-height` 被改为 `normal`,导致文字不再居中。
3. 删除恢复逻辑仅重置了 `border` 和 `background`,未恢复 `width`、`height`、`lineHeight` 等尺寸属性。
4. `execCommand` 的对齐命令实现过于粗暴,会直接修改 DOM 树结构以创建对齐容器,无法安全地处理混合排版(文字 + 交互元素)。
**C. 解决问题方案**
1. **视频按钮位置**:将上传按钮从 `videos.map()` 之前移至之后,保持所有样式和点击逻辑不变。
2. **占位符文字绝对居中**
- 将 `.placeholder-text` 的样式统一改为 `position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); display:block; width:100%;`
- 给所有表格内的 `.image-placeholder` 父容器添加 `position:relative;`inline-block 和签名占位符原本已有)
- 修改范围覆盖 `defaultContent.ts`8 个占位符)、`ReportEditor.tsx`Modal 插入 + 删除恢复)、`TemplateManage.tsx`Modal 插入 + 删除恢复)
3. **删除后恢复尺寸**:在删除恢复逻辑中增加:
```ts
const mw = placeholder.style.maxWidth;
const mh = placeholder.style.maxHeight;
if (mw) placeholder.style.width = mw;
if (mh) { placeholder.style.height = mh; placeholder.style.lineHeight = mh; }
placeholder.style.textAlign = 'center';
placeholder.style.verticalAlign = 'middle';
placeholder.style.justifyContent = 'center';
placeholder.style.alignItems = 'center';
```
同时根据占位符原始宽度(`maxWidth || width`)判断显示「插图」(<80px或「插入/点击放置图片」。
4. **安全对齐**:弃用 `execCommand('justifyLeft'/'justifyCenter'/'justifyRight')`,新增 `changeAlignment(align)` 方法:
- 通过 `window.getSelection()` 获取选区
- 使用 `closest('p, div, td, h1, h2, h3, li')` 找到最近的块级祖先
- 直接设置 `(block as HTMLElement).style.textAlign = align`
- 同步保存内容快照
- 对齐按钮增加 `onMouseDown={(e) => e.preventDefault()}` 防止编辑器失焦
**D. 后续如何避免问题**
- 当修改 `image-placeholder` 的创建或恢复逻辑时,必须在所有入口同步更新:`defaultContent.ts`(静态模板)、`ReportEditor.tsx`(运行时插入/填充/删除恢复)、`TemplateManage.tsx`(模板管理)。
- 任何涉及 `execCommand` 的富文本操作都应评估其安全性,优先使用直接 DOM 样式操作(如 `style.textAlign`、`style.lineHeight`)替代,避免浏览器原生命令对复杂 DOM 结构的不可控修改。
- 绝对定位的居中方案(`transform: translate(-50%, -50%)`)虽然效果稳定,但要求父容器必须带有 `position: relative`,修改时需同步检查所有父容器的样式。