一千萬個為什麽

搜索

保存和恢復contentEditable div的插入位置

我有一個 contentEditable div, innerHTML 可以在編輯時通過AJAX更新。問題是,當您更改div的內容時,它會將光標移動到div的末尾(或根據瀏覽器失去焦點)。在更改 innerHTML 然後恢復之前,什麽是存儲插入位置的良好跨瀏覽器解決方案?

最佳答案

回到2016年:)
在我遇到這個解決方案後,它並不適合我,因為我的DOM在每次打字後都完全取代了。我做了更多的reasech,並提供了簡單的解決方案,保存光標的角色的位置,為我工作完美

想法很簡單。

  1. 在插入符號之前找到charachters的長度並保存。
  2. 更改DOM。
  3. 使用 TreeWalker上下文節點文本節點上行走並計算字符,直到我們得到正確的文本節點</代碼>及其中的位置

兩個邊緣案例:

  1. 內容已完全刪除,因此沒有文本節點
        so :將光標移動到上下文節點的開頭

  2. 內容少於 index 指向的內容:
        so :將光標移動到最後一個節點的末尾

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

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"/>
  

Edit the CSS Snippet

 

    p { color: red }
<script >
  var code = document.getElementsByTagName('code')[0];
  
  code.addEventListener('input',function() {
        var restore = saveCaretPosition(this);
        Prism.highlightElement(this);
        restore();
    })
</script>
</div> </div>

轉載註明原文: 保存和恢復contentEditable div的插入位置