Получить положение курсора в области contentEditable, содержащей содержимое HTML
у меня есть contentEditable элемент (может быть p, div, ...) и я хотел бы получить позицию каретки (курсора) в нем. Обычно я могу достичь этого с помощью этого фрагмента кода:
var position = window.getSelection().getRangeAt(0).startOffset;
Это прекрасно работает, пока элемент содержит только текст. Но когда элемент содержит некоторое форматирование HTML, возвращенная позиция относительно позиции каретки внутри включенного элемента HTML.
предположим, что содержимое contentEditable элемента таково:
AB<b>CD</b>EF
Если каре внутри <b></b>
, скажем, между C и D, возвращаемая позиция с вышеуказанным кодом равна 1 вместо 3 (подсчитывается с начала содержимого contentEditable элемента)
может ли кто-нибудь придумать решение для этого ?
3 ответа:
обновление
Я написал более простую версию этого, которая также работает в IE
https://stackoverflow.com/a/4812022/96100
Ответ
это на самом деле более полезный результат, чем символа в тексте всего документа:
startOffset
свойства спектр дом (который является тем, чтоwindow.getSelection().getRangeAt()
returns) - это смещение относительно егоstartContainer
свойство (которое, кстати, не всегда является текстовым узлом). Однако, если вы действительно хотите смещение символа, вот функция, которая это сделает.вот живой пример:http://jsfiddle.net/timdown/2YcaX/
вот функция:
function getCharacterOffsetWithin(range, node) { var treeWalker = document.createTreeWalker( node, NodeFilter.SHOW_TEXT, function(node) { var nodeRange = document.createRange(); nodeRange.selectNode(node); return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; }, false ); var charCount = 0; while (treeWalker.nextNode()) { charCount += treeWalker.currentNode.length; } if (range.startContainer.nodeType == 3) { charCount += range.startOffset; } return charCount; }
Это очень старый пост, но все же одним из первых результатов поиска в Google, так что, возможно, еще пригодится. Это работает для меня, чтобы получить правильное положение с учетом html-тегов и новых строк, а также (протестировано на Firefox):
function getCaretPosition (node) { var range = window.getSelection().getRangeAt(0), preCaretRange = range.cloneRange(), caretPosition, tmp = document.createElement("div"); preCaretRange.selectNodeContents(node); preCaretRange.setEnd(range.endContainer, range.endOffset); tmp.appendChild(preCaretRange.cloneContents()); caretPosition = tmp.innerHTML.length; return caretPosition; }
Он использует функциональность cloneContents для того, чтобы получить фактический HTML и добавляет пробуя на временное див для того, чтобы получить длину в HTML.