document.execcommand已废弃,chrome 93+等新版浏览器默认禁用,应改用beforeinput+selection+range手动操作dom或接入现代编辑器。

旧版 HTML 重构不是“把 <font></font> 换成 <span></span>”就能完事的事——它本质是把一套运行在 IE6 时代的 DOM 逻辑,塞进现代浏览器的渲染流水线里,还不能崩、不能卡、不能丢交互。直接重写成本太高,但只做表面替换,上线后光标乱跳、样式错位、document.execCommand 失效、中文输入法上屏延迟,全是大概率事件。
document.execCommand 失效了,怎么救?
这不是配置没开,是标准已移除。Chrome 93+、Firefox 89+、Safari 15.4+ 默认返回 false,且不报错,你看着按钮点了,DOM 就是不动。
- 别再 patch
execCommand的返回值——它底层已被禁用,补丁只能骗过 JS 层,骗不过渲染引擎 - 最轻量级解法:改用
beforeinput+getSelection()+Range手动包裹文本节点,比如加粗就插入<strong></strong>包裹选区 - 若已有大量插件依赖
queryCommandState,需同步改状态判断逻辑:不再查浏览器状态,改为遍历当前节点的node.parentElement?.tagName === 'STRONG' - polyfill(如
execCommand-polyfill)仅适用于纯展示型编辑器,对撤销栈、嵌套格式、实时协作等场景完全不可靠
contenteditable 光标和粘贴行为全乱了
老系统靠 range.selectNodeContents() 定位,新浏览器里这会触发 layout thrashing,光标跳到顶部或消失;粘贴时 insertHTML 插入的样式被过滤、脚本被剥离、甚至引发 XSS。
- 粘贴处理必须接管
paste事件,并用event.clipboardData.getData('text/html')取原始 HTML,再用 DOMParser 清洗:移除style标签、过滤onxxx属性、标准化class命名 - 光标恢复不能依赖
selection.addRange(),要先用getSelection().getRangeAt(0).startOffset记位置,再通过editorView.state.doc.resolve(pos)(ProseMirror)或editor.commands.focus()(Tiptap)重建 - 中文输入法场景下,
input事件太晚,beforeinput在 Safari 15.4 前不可用——必须双监听,并在compositionend后手动校验一次光标位置
老式表格布局 + 内联样式怎么平滑过渡?
直接上 Flex/Grid 会炸掉整个页面结构,但继续用 <table> 嵌套 + <code>align="center" + border="0",现代 CSS 重置规则一开就全跑偏。
- 第一步不是改 HTML,而是加一层
<div class="legacy-table-wrapper"> 包住所有老表格,在 CSS 中用 <code>.legacy-table-wrapper table { table-layout: fixed; width: 100%; }锁死尺寸 - 内联样式优先级太高,不要试图全局
[style] { all: unset; }——会导致表单控件失样式;应按需提取:把style="color:red"提炼为class="text-danger",再用 JS 扫描替换 - 避免直接删
<font></font>标签——它可能被 JS 用document.getElementsByTagName('font')查找;先保留标签,CSS 里设font { font-family: inherit; color: inherit; },等 JS 层迁移完成再删
最难的不是语法替换,是那些藏在 setTimeout 里等 DOM ready 的胶水代码、用 document.all 判断 IE 的兼容分支、以及靠 offsetLeft + clientWidth 手算弹窗位置的定位逻辑——这些不会报错,但会在 Chrome 里慢半拍、在 Safari 里偏 2px、在 Firefox 里偶尔失效。重构时得把它们拎出来,单独验证,而不是指望“看起来一样”。











