[英]Add character to multi-line selection in Codemirror on each line of selection
[英]character position of a multi-line selection within a content editable div using javascript
请看一下这个小提琴:
https://jsfiddle.net/darrengates/jwx41Lkz/
在这个例子中,我有一个 3 行的可编辑 div。 我正在尝试获取选择的起始字符 position 和结束字符 position。
这似乎只适用于第一行。 如果我突出显示超过 1 行,则值不正确(请参阅注释以获取解释)。
当它跨越多行时,如何获得启动和结束字符position的选择? (即,字符 position 从整个 div 的第一个字母开始,例如,“第二行”中的“s”大约是字符 position 11)。
这是我到目前为止所拥有的(可在小提琴中运行):
<div id="test" contenteditable="true" class="selecttest">
first line<br />
second line<br />
third line
</div>
.selecttest {
width: 400px;
height: 200px;
border: 1px solid black;
padding: 5px;
font-size: 20px;
}
function getSelection() {
const sel = document.getSelection() || window.getSelection();
// note: if I highlight the 2nd and 3rd lines
// start and end values are 1, 11
// they should be about 11 and 22 (or so)
// on account of the existence of the first line
let start = sel.baseOffset
let end = sel.extentOffset
// if selected from right to left, reverse...
if ( start > end ) {
const temp = start;
start = end;
end = temp;
}
console.log('start, end', start, end)
}
$("#test").on('mouseup', function() {
getSelection();
})
似乎有很多与获取选定文本相关的 SO 帖子,但与获取选定字符位置相关的答案在选择多行时都失败了。
由于您想在一个范围内测量 position,您应该使用一个范围 object 而不是选择 object。
关于此代码笔的建议> https://codepen.io/aSH-uncover/pen/ExEdXwy
主要技巧是解决范围是否在同一个容器内的两种情况:)
function getSelection() {
const sel = document.getSelection() || window.getSelection();
const range = sel.getRangeAt(0)
let rangeContainer = range.commonAncestorContainer
let same = false
if (rangeContainer === range.startContainer) {
same = true
rangeContainer = range.startContainer.parentElement
}
let start = -1
let end = -1
const list = rangeContainer.childNodes
let offset = 0
for (let i = 0 ; i < list.length ; i++) {
const current = list[i]
if (current === range.startContainer) {
start = offset + range.startOffset
if (same) {
end = offset + range.endOffset
break
}
} else if (current === range.endContainer) {
end = offset + range.endOffset
break
}
if (current.nodeName === '#text') {
offset += current.length
}
}
console.log('start, end', start, end)
}
编辑:如果你想支持更复杂的文本(比如带有跨度的 div),你将不得不改进这个 function 并包括一些递归的东西:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.