我正在尝试获取具有多个 html 元素和多行的 contenteditable div 中的插入符号位置。
我找到了一个很好的解决方案,仅根据文本返回插入符位置 - 这不是我正在寻找的。
迄今为止我找到的最佳解决方案已在此处进行了解释。问题是这不会返回多行 div 场景中的插入符号位置。
请帮忙。提前致谢,
max-width
以查看差异) ).这也是主要问题:不仅要检查元素的显示设置,还要计算其内容是否适合可编辑 div 的剩余宽度,这在检查下一行和子元素时变得更加复杂.
在我看来,这并不是真正可以解决的,因为您还可以为每个元素设置不同的可继承字体设置、边距、填充、高度/宽度等。
因此,我只找到了一个简单 HTML 元素的解决方案,可以为您提供一个开始。即使在这里,您仍然需要添加所有前(子)元素必须有多少换行符来计算实际行的逻辑(由于 div 2 中的换行符,div 3 中的行是错误的)。
https://jsfiddle.net/Lndspaov/
function getCaretPosition(elementId) {
var line = 1;
var position = 0;
var element = document.getElementById(elementId);
var selection = window.getSelection();
if (selection.focusNode != null) {
if (isDescendantOf(selection.focusNode, element)) {
var node = selection.focusNode;
position = selection.focusOffset;
if (node != null && node.nodeValue != null) {
position -= node.nodeValue.search(/\S/);
}
while (node != null) {
if (node == element) {
break;
}
if (node.previousSibling != null) {
node = node.previousSibling;
if (node.innerText != null) {
var count = (node.innerText.match(/\n/g) || []).length;
if (count == 0) {
line++;
} else {
line += count;
}
}
} else {
node = node.parentNode;
}
}
}
}
return {
line: line,
position: position
};
}
function isDescendantOf(node, parent) {
while (node != null) {
if (node == parent) {
return true;
}
node = node.parentNode;
}
return false;
}
var $edit = $('#edit'),
$pos = $('#pos'),
$line = $('#line');
$edit.mouseup(function (){
var pos = getCaretPosition('edit');
$pos.html(pos.position);
$line.html(pos.line);
});
.edit {
border: 1px solid black;
max-width: 350px;
}
.inlined {
background: #cccc00;
border: 1px solid red;
display: inline;
}
.error {
background: #cc8888;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
click inside:<br /><br />
<div class="edit" id="edit" contentEditable="true">
<div>div 1: here is some text</div>
<div>div 2: some more text<br />with a linebreak</div>
<div class="error">
div 3: here the issues begin (line is wrong)
</div>
<div class="error inlined">div 4: these divs have 'display:inline'</div>
<div class="error inlined">div 5: which is also problematic</div>
</div>
<br />
line: <label id="line"></label><br />
position: <label id="pos"></label>