назад в 2016:)
После того, как я наткнулся на это решение, оно меня не устраивало, потому что мой DOM заменялся полностью после каждой печати.Я провел больше исследований и пришел к простому решению, которое сохраняет курсор по позиции персонажа, которое мне подходит идеально .
Идея очень проста.найдите длину символов перед кареткой и сохраните ее.
измените DOM. , используя
TreeWalker
, чтобы пройти только по
text nodes
из
context node
и считая символы, пока мы не получим право
text node
и положение внутри него
Два крайних случая:
содержимое полностью удалено, поэтому text node
:
so : переместить курсор в начало контекстаузел
меньше содержимого, чем указано index
:
так : переместить курсор в конец последнего узла
function saveCaretPosition(context){
var selection = window.getSelection();
var range = selection.getRangeAt(0);
range.setStart( context, 0 );
var len = range.toString().length;
return function restore(){
var pos = getTextNodeAtPosition(context, len);
selection.removeAllRanges();
var range = new Range();
range.setStart(pos.node ,pos.position);
selection.addRange(range);
}
}
function getTextNodeAtPosition(root, index){
var lastNode = null;
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT,function next(elem) {
if(index >= elem.textContent.length){
index -= elem.textContent.length;
lastNode = elem;
return NodeFilter.FILTER_REJECT
}
return NodeFilter.FILTER_ACCEPT;
});
var c = treeWalker.nextNode();
return {
node: c? c: root,
position: c? index: 0
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/prism.min.js"></script>
<link href="https://rawgit.com/PrismJS/prism/gh-pages/themes/prism.css" rel="stylesheet"/>
<style>
*{
outline:none
}
</style>
<h3>Edit the CSS Snippet </H3>
<pre>
<code class="language-css" contenteditable=true >p { color: red }