我正在使用一个`contentEditable span`,希望将一个`position: absolute`的元素放在光标所在的同一行。问题出现在文本换行时,因为它无法适应 - 换行的第一个和最后一个位置有奇怪的行为。
对于它们两个来说,当我在第二行的第一个位置时,`getBoundingClientRect()`的`y`偏移量等于第一行的偏移量,然而如果我在第二行再移动一个位置,`y`偏移量就正确地匹配第二行了。
在下面的代码片段中,这种行为在Firefox中显示出来。对于Chrome来说,它似乎工作得很好,尽管在我的完整实现中它也有不精确的行为,但我已经能够解决了Chrome的问题。然而对于Firefox来说,第一行的最后一个位置的`offset`等于第一行,第二行的第一个位置的`offset`等于第一行,之后它就正常工作了。
在这个例子中,跳到第一行的最后一个位置,并注意控制台中的
对于它们两个来说,当我在第二行的第一个位置时,`getBoundingClientRect()`的`y`偏移量等于第一行的偏移量,然而如果我在第二行再移动一个位置,`y`偏移量就正确地匹配第二行了。
在下面的代码片段中,这种行为在Firefox中显示出来。对于Chrome来说,它似乎工作得很好,尽管在我的完整实现中它也有不精确的行为,但我已经能够解决了Chrome的问题。然而对于Firefox来说,第一行的最后一个位置的`offset`等于第一行,第二行的第一个位置的`offset`等于第一行,之后它就正常工作了。
在这个例子中,跳到第一行的最后一个位置,并注意控制台中的
CURRENT_TOP
值显示为16
。如果你向右移动一个位置,光标已经在下一行,它仍然显示16
。如果你再向右移动一个位置,它将显示36
。
const textEl = document.getElementById("myText")
textEl.addEventListener("keyup", (event) => {
const domSelection = window.getSelection();
if (domSelection && domSelection.isCollapsed && domSelection.anchorNode) {
let offsetNewLine = 0;
const domRange = domSelection.getRangeAt(0);
const rect = domRange.getBoundingClientRect();
const rects = domRange.getClientRects();
const newRange = document.createRange();
const newRangeNextOffset = domSelection.anchorNode.textContent.length < domSelection.anchorOffset + 1 ? domSelection.anchorOffset : domSelection.anchorOffset + 1
newRange.setStart(domSelection.anchorNode, newRangeNextOffset);
newRange.setEnd(domSelection.anchorNode, newRangeNextOffset);
const nextCharacterRect = newRange.getBoundingClientRect();
console.log(`CURRENT_TOP: ${rect.y}, NEXT_CHAR_TOP: ${nextCharacterRect.y}`);
}
})
.text-container {
width: 500px;
display: inline-block;
border: 1px solid black;
line-height: 20px;
padding: 5px;
}
<span id="myText" class="text-container" contentEditable="true">Go on the last position in the first row and come it to first position in the second row</span>
console.log()
行使用了错误的语法。我已经为您纠正了这个问题,并将代码移入了一个内联片段中,这样您更有可能得到一些答案,因为人们更容易看到您所谈论的代码。 - undefineddomSelection.anchorNode.textContent[newRangeNextOffset]
的值以查看它认为下一个字母是什么时,它比我预期的位置提前了一个位置。通过将设置newRangeNextOffset
值的三元语句中的+1
移动,我成功修复了这个问题。为什么不直接使用domRange.endOffset
来获取光标位置呢? - undefinedDomSelection
和domRange
是折叠的,但是domSelection.anchorNode.textContent[domRange.endOffset]
将显示光标右侧的字符。当你在第一行的末尾时,下一个字符是" "
,所以我的想法是获取下一个字符的位置,并检查它是否已经在第二行,但这还不够,因为第二行的第一个位置仍然等于第一行。我可以使用currentOffset + 2
,但这在Chrome上不起作用,因为它会认为我在第二行提前一个字符。 - undefined