取得contenteditable中光标的坐标位置

开发安科编辑器时,需要在contenteditable中临时生成一个“ROLLDICE”输入框,并把输入框准确放在用户输入光标的位置。

常见的做法直接使用getRangeAt(0).getBoundingClientRect(),但当光标位于行首时,返回值将为0。因此在这种情况下需要临时添加一个span并用于计算出正确位置。

但如果光标处于文字之间时,添加span会导致光标移位,因此必须只在光标处于行首时使用这种方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//get the position of the cursor
let selection = window.getSelection();
let range = selection.getRangeAt(0);
let rect = range.getBoundingClientRect();
let topPosition = rect.top;
let leftPosition = rect.left;
//if the cursor is at the beginning of a line, the position is 0
if (topPosition === 0) {
//create a hidden node to get the correct position of the cursor
document.execCommand('insertHTML', false, '<span id="hiddenSpan"></span>');
let hiddenNode = document.getElementById('hiddenSpan');
let rect = hiddenNode.getBoundingClientRect();
topPosition = rect.top;
leftPosition = rect.left;
hiddenNode.parentNode.removeChild(hiddenNode);
}
// create the dicediv
// dicediv position must be absolute
let dicediv = document.createElement('div');
dicediv.className = "dice_div";
dicediv.style.left = leftPosition + "px";
dicediv.style.top = topPosition + "px";
editDiv.appendChild(dicediv);