当文本因点击编辑器而移位时,将' Selection '移动到正确位置



我有一个编辑器,每当它被模糊时隐藏特定的文本事件-所有由regexp匹配的文本都被移动(通过registerNodeTransform)在特殊节点HidingNode下,其中HidingNode extends TextNode。当编辑器不聚焦时,HidingNode的所有实例都得到display: none

这意味着每当我点击输入时,HidingNode的所有实例都会突然出现,并移动其余的文本。单击后,Selection移动到光标后面的任何节点。所有HidingNode出现。我想改变这一点,以便Selection移动到之前光标下的任何节点(和偏移量)。点击已注册(也就是节点用户在点击时实际上是悬停在上面)。

我试图以多种方式测量Selection的位置,希望在HidingNodes出现之前捕获它,但我只能得到最终位置,HidingNodes已经可见。

我尝试用以下方式手动补偿移位:

editor.update(() => {
const allTextNodes = $getRoot().getAllTextNodes()
const totalCaretPosition = $getCaretPositionInNodeList(allTextNodes)
if (totalCaretPosition === null) return
const nonHidingNodes = allTextNodes.filter(node => !$isHidingNode(node))
$moveCaretToNthPositionInNodeList(nonHidingNodes, totalCaretPosition)
})

这可以正常工作,但是只适用于等宽字体-否则出现的HidingNode字符的数量很少与它们所取代的字符的数量匹配。

有可能做我想做的事吗,还是我运气不好?

我用的是@lexical/react

非常感谢🙏

所以我找到了一个解决方法。我不是很喜欢它,但它现在可以完成工作。

ContentEditable组件中,而不是

const isFocused = !useIsFocused()
return <StyledDiv $hideHiddenNodes={!isFocused} /* ... */ />

我做

const isFocused = useIsFocused()
const [isFocusedDelayed, setIsFocusedDelayed] = useState(isFocused)
useLayoutEffect(() => {
setTimeout(() => setIsFocusedDelayed(isFocused), 0)
}, [isFocused])
return <StyledDiv $hideHiddenNodes={!isFocusedDelayed} /* ... */ />

这似乎给了编辑器足够的空间在隐藏节点出现之前确定焦点。

我还在寻找一个合适的答案,因为这似乎不太可靠。

最新更新