it-swarm.com.de

Holen Sie sich die Position des Carets (Cursors) im contentEditable-Bereich, der HTML-Inhalt enthält

Ich habe ein contentEditable-Element (kann p, div, ... sein) und möchte die Cursorposition darin erhalten. Normalerweise kann ich das mit folgendem Code erreichen:

var position = window.getSelection().getRangeAt(0).startOffset;

Dies funktioniert gut, während das Element nur Text enthält. Wenn das Element jedoch eine HTML-Formatierung enthält, ist die zurückgegebene Position relativ zur Einfügeposition im enthaltenen HTML-Element.

Angenommen, der Inhalt des contentEditable-Elements lautet wie folgt:

AB<b>CD</b>EF

Wenn Caret drin ist <b></b>, sagen wir zwischen C und D, die zurückgegebene Position mit dem obigen Code ist 1 statt 3 (gerechnet vom Anfang des Inhalts des contentEditable-Elements)

Kann jemand eine Lösung dafür finden?

56
Frodik

AKTUALISIEREN

Ich habe eine einfachere Version davon geschrieben, die auch in IE <9 funktioniert:

https://stackoverflow.com/a/4812022/961

Alte Antwort

Dies ist tatsächlich ein nützlicheres Ergebnis als ein Zeichenversatz innerhalb des gesamten Dokuments: Die Eigenschaft startOffset eines DOM-Bereichs (was window.getSelection().getRangeAt() zurückgibt) ist ein Versatz relativ zu seiner startContainer -Eigenschaft (die übrigens nicht unbedingt immer ein Textknoten ist). Wenn Sie jedoch wirklich einen Zeichenversatz möchten, finden Sie hier eine Funktion, die dies erledigt.

Hier ist ein Live-Beispiel: http://jsfiddle.net/timdown/2YcaX/

Hier ist die Funktion:

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;
}
51
Tim Down

Dies ist ein sehr alter Beitrag, aber immer noch eines der ersten Ergebnisse der Google-Suche, also vielleicht immer noch nützlich. Dies funktioniert bei mir auch unter Berücksichtigung von HTML-Tags und Zeilenumbrüchen (getestet in 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;
}

Es verwendet die cloneContents-Funktionalität, um den tatsächlichen HTML-Code abzurufen, und hängt das Dokumentfragment an ein temporäres div an, um die HTML-Länge abzurufen.

6
Andrea

Wenn Sie ein Element einfügen möchten, können Sie Folgendes versuchen:

// Get range
var range = document.caretRangeFromPoint(event.clientX, event.clientY);
if (range)
  range.insertNode(elementWhichYouWantToAddToContentEditable);
1
Antti