获取具有多行的 contenteditbable div 中的插入符位置

问题描述 投票:0回答:1

我正在尝试获取具有多个 html 元素和多行的 contenteditable div 中的插入符号位置。

我找到了一个很好的解决方案,仅根据文本返回插入符位置 - 这不是我正在寻找的。

迄今为止我找到的最佳解决方案已在此处进行了解释。问题是这不会返回多行 div 场景中的插入符号位置。

请帮忙。

提前致谢,

javascript html
1个回答
0
投票
第一个问题是,您是否想按元素/段落或实际显示的内容检查新行,这可能会有所不同,具体取决于可编辑 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>

© www.soinside.com 2019 - 2024. All rights reserved.