IOS设备Shadow Dom环境下Safari/Chrome的Tiptap输入法选中异常问题
iOS Shadow Dom环境下Tiptap输入CJK语言(日文/中文/韩文等)的异常修复方案
问题概述
在iOS设备的Safari/Chrome浏览器中,Shadow Dom环境下使用Tiptap输入日文、中文、韩文、泰文等CJK类语言时,会出现以下异常行为:
- 输入日文并选择预测文本后继续输入,所有已输入文本被删除
- 点击回车键时,不会新增换行,而是直接替换当前文本
根因分析
Tiptap基于ProseMirror构建,负责选区管理的prosemirror-state依赖prosemirror-view@1.27.0,该版本存在Shadow Dom场景下的选区同步bug,导致iOS系统输入法与编辑器的选区状态不匹配,进而引发输入逻辑错乱。
可行解决办法
1. 升级prosemirror-view至最新稳定版
该问题在prosemirror-view的后续版本中已被修复,直接升级依赖即可解决:
# 使用npm更新 npm update prosemirror-view # 使用yarn更新 yarn upgrade prosemirror-view
升级完成后,验证Shadow Dom环境下编辑器的CJK语言输入、预测文本选择及换行功能是否恢复正常。
2. 自定义ProseMirror插件修复选区同步
若无法直接升级依赖,可通过自定义插件手动同步编辑器选区与DOM选区:
import { Plugin } from 'prosemirror-state' const shadowDomSelectionFixPlugin = new Plugin({ view(editorView) { const syncSelection = () => { const { selection: editorSelection } = editorView.state const domSelection = window.getSelection() if (editorView.dom.shadowRoot && domSelection.rangeCount > 0) { const range = domSelection.getRangeAt(0) const $from = editorView.posAtDOM(range.startContainer, range.startOffset) const $to = editorView.posAtDOM(range.endContainer, range.endOffset) if ($from && $to && !editorSelection.eq(editorView.state.selection.set($from, $to))) { editorView.dispatch(editorView.state.tr.setSelection(editorView.state.selection.set($from, $to))) } } } // 监听输入和选区变化事件,触发同步 editorView.dom.addEventListener('input', syncSelection) editorView.dom.addEventListener('selectionchange', syncSelection) return { destroy() { editorView.dom.removeEventListener('input', syncSelection) editorView.dom.removeEventListener('selectionchange', syncSelection) } } } }) // 将插件添加到Tiptap编辑器配置 const editor = new Editor({ extensions: [ // ...其他扩展 shadowDomSelectionFixPlugin ], // ...其他配置 })
该插件通过监听输入与选区变化事件,手动校正Shadow Dom下的选区错位问题,确保编辑器内部状态与DOM选区一致。
3. 临时规避方案:移出Shadow Dom环境
若上述方案无法快速落地,可暂时将编辑器从Shadow Dom容器中移出,直接挂载到常规DOM节点下,可立即规避该问题,但需评估业务对Shadow Dom的依赖需求。
内容的提问来源于stack exchange,提问作者tamir goldman
相关产品推荐
相关产品推荐

