sonic: Position des texcursors in einem Element ermitteln/setzen

Beitrag lesen

Hier mal eine Variante dessen, was ich gebaut habe. Das Auslesen klappt, beim Setzen gibt es immer den Fehler (Zum Ausprobieren kannst Du einfach irgendwo im Test-String eine Eingabe machen, dann wird die Caret-Position angezeigt. Wenn Du anschließend auf den Button klickst, wird das innerHTML ersetzt und der Cursor sollte danach wieder auf die richtige Position geschoben werden, was aber leider nicht passiert).

  
<div id="container"></div>  
<div id="pos"></div>  
<input type="button" onclick="javascript:replace_content();" value="test"/>  
  
<script type="text/javascript">  
var ed = document.createElement('pre');  
  
ed.innerHTML = '<span class="other"><span class="preproc">&lt;?php</span></span><span class="php"><span class="function"> echo </span><span class="var">$test</span><span class="interpunction">;</span><span class="preproc">?></span></span>';  
  
ed.contentEditable = true;  
  
document.getElementById('container').appendChild(ed);  
  
ed.onkeyup = function(e) {  
    var sel = window.getSelection();  
    var range = document.createRange();  
  
    range.setStart(ed, 0);  
    range.setEnd(sel.anchorNode, sel.anchorOffset);  
  
    var caret_pos = range.toString().length;  
    document.getElementById('pos').innerHTML = caret_pos;  
}  
  
function replace_content() {  
    ed.innerHTML = '<span class="other"><span class="preproc">&lt;?php</span></span><span class="php"><span class="function"> echo </span><span class="var">$test</span><span class="interpunction">;</span></span>';  
  
    var caret_pos = parseInt(document.getElementById('pos').innerHTML);  
  
    var ptr = 0;  
  
    outer: for (var i = 0; i < ed.childNodes.length; i++) {  
      for (var j = 0; j < ed.childNodes[i].childNodes.length; j++) {  
            var tmp = ed.childNodes[i].childNodes[j];  
            if (tmp.textContent.length + ptr < caret_pos) {  
                ptr += tmp.textContent.length;  
                continue;  
            }  
            else {  
                var new_anchor = tmp;  
                var anchor_offset = caret_pos - ptr;  
                break outer;  
            }  
        }  
    }  
  
    if (new_anchor) {  
        console.log('Anchor Content: "' + new_anchor.innerHTML + '"');  
        console.log('Anchor Offset' + anchor_offset);  
        var sel = window.getSelection();  
        var new_range = document.createRange();  
        new_range.setStart(new_anchor, anchor_offset);  
        new_range.setEnd(new_anchor, anchor_offset);  
        sel.addRange(new_range);  
    }  
  
}  
  
</script>