【问题标题】:How to get current cursor's position in draft.js?如何获取当前光标在 Draft.js 中的位置?
【发布时间】:2021-11-30 17:06:30
【问题描述】:
对于我的draftjs 项目,我想让用户插入一个链接。为此,我在按下快捷方式 cmk + k 后创建了一个弹出窗口。
为了更好的用户体验,我目前正在尝试智能对齐弹出窗口。
见上图,我可以将弹出窗口定位在当前焦点线的下方。编辑器容器的边界矩形对象和当前选择的边界矩形将包含足够的信息让我完成计算。
但是,在其他情况下,只有空行时:
(弹窗前光标的位置在编辑器的末尾)
window.getSelection().getRangeAt(0).getBoundingClientRect() 将返回每个值为 0 的 DOMRect 对象。在 dom 或 draftjs 中是否有任何方法可以让我获得足够的信息来智能对齐弹出窗口?所以弹出窗口可以在当前光标位置附近弹出。
【问题讨论】:
标签:
javascript
html
reactjs
next.js
draftjs
【解决方案1】:
为了解决这个问题,我使用光标的块索引乘以行高+一些偏移量来实现在选择空行时从顶部正确放置。
这是我的“计算弹出窗口位置”函数的代码。 I've excluded parts for getting the top/left positions when a line with text is selected and just included when I need to account for lines with no text when getBoundingClientRect() returns null.
const singleLineHeightOffset = 28;
const topBlankLineOffset = 15;
let position = getVisibleSelectionRect(window);
// If there is a visible selection area
if (position) {
// Get ref of editor via prop and location of div if exists
let editorRef = forwardedRef;
element = ReactDOM.findDOMNode(editorRef.current) as HTMLElement;
if (element) {
// Code here to calculate when a line with text is selected
} else {
// Else if no text selected on line
// Get current block position of cursor
const currentBlockKey = editorState.getSelection().getStartKey();
const currentBlockIndex = editorState
.getCurrentContent()
.getBlockMap()
.keySeq()
.findIndex((k) => k === currentBlockKey);
let emptyLineTopHeight =
singleLineHeightOffset * (currentBlockIndex + 1) - 5;
// If first line of editor, add offset for toolbar/padding
if (currentBlockIndex === 0) emptyLineTopHeight += topBlankLineOffset;
setTopPosition(emptyLineTopHeight);
}
这将检测空光标所在的行,然后通过乘以行高来创建顶部偏移。您可能需要像我一样处理偏移量和边缘情况,例如初始行。