我有一个编辑器,每当它被模糊时隐藏特定的文本事件-所有由regexp匹配的文本都被移动(通过registerNodeTransform)在特殊节点HidingNode
下,其中HidingNode extends TextNode
。当编辑器不聚焦时,HidingNode
的所有实例都得到display: none
。
这意味着每当我点击输入时,HidingNode
的所有实例都会突然出现,并移动其余的文本。单击后,Selection
移动到光标下后面的任何节点。所有HidingNode
出现。我想改变这一点,以便Selection
移动到之前光标下的任何节点(和偏移量)。点击已注册(也就是节点用户在点击时实际上是悬停在上面)。
我试图以多种方式测量Selection
的位置,希望在HidingNode
s出现之前捕获它,但我只能得到最终位置,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} /* ... */ />
这似乎给了编辑器足够的空间在隐藏节点出现之前确定焦点。
我还在寻找一个合适的答案,因为这似乎不太可靠。