我有一个contenteditable div,其中我有多个标签(br,b,u,i)和文本,我需要获得相对于div的插入位置,包括所有标签。
例如:
<div id="h" contenteditable="true">abc<b>def<br>ghi</b>jkl</div>
如果光标在g和h之间,我需要插入位置为14。 问题是找到的使用treeWalker的方法在这种情况下不起作用。 找不到粗体标签......可能是因为它没有关闭。 我也尝试了几种方法,但仍然没有运气。
我需要它才能在Firefox中运行。 谢谢。
答案 0 :(得分:19)
直接链接到jsfiddle: https://jsfiddle.net/TjXEG/1/
功能代码:
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
if (typeof window.getSelection != "undefined") {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var textRange = document.selection.createRange();
var preCaretTextRange = document.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
function showCaretPos() {
var el = document.getElementById("test");
var caretPosEl = document.getElementById("caretPos");
caretPosEl.innerHTML = "Caret position: " + getCaretCharacterOffsetWithin(el);
}
document.body.onkeyup = showCaretPos;
document.body.onmouseup = showCaretPos;
答案 1 :(得分:3)
只需这样做,因此有一些工作解决方案(可能需要进行一些测试)
基本理念是:
使用此方法获取textContent位置:Get caret (cursor) position in contentEditable area containing HTML content
将元素的innerHTML迭代到textContent位置
如果遇到html标记或实体,请遍历它直到普通char,然后继续
示例代码:
function getHTMLCaretPosition(element) {
var textPosition = getCaretPosition(element),
htmlContent = element.innerHTML,
textIndex = 0,
htmlIndex = 0,
insideHtml = false,
htmlBeginChars = ['&', '<'],
htmlEndChars = [';', '>'];
if (textPosition == 0) {
return 0;
}
while(textIndex < textPosition) {
htmlIndex++;
// check if next character is html and if it is, iterate with htmlIndex to the next non-html character
while(htmlBeginChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) {
// console.log('encountered HTML');
// now iterate to the ending char
insideHtml = true;
while(insideHtml) {
if (htmlEndChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) {
if (htmlContent.charAt(htmlIndex) == ';') {
htmlIndex--; // entity is char itself
}
// console.log('encountered end of HTML');
insideHtml = false;
}
htmlIndex++;
}
}
textIndex++;
}
//console.log(htmlIndex);
//console.log(textPosition);
// in htmlIndex is caret position inside html
return htmlIndex;
}