61 Stimmen

Ermittelt die Position des Cursors im Bereich contentEditable, der den HTML-Inhalt enthält

Ich habe contentEditable Element (kann p, div, ...) und ich möchte Caret (Cursor) Position in es zu erhalten. Ich kann es normalerweise mit diesem Stück Code erreichen:

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

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

Nehmen wir an, der Inhalt des contentEditable-Elements ist dieser:

AB<b>CD</b>EF

Wenn der Cursor innerhalb von <b></b> Sagen wir, zwischen C und D, ist die zurückgegebene Position mit obigem Code 1 statt 3 (gezählt vom Anfang des Inhalts des contentEditable-Elements)

Kann jemand eine Lösung für dieses Problem finden?

54voto

Tim Down Punkte 304837

UPDATE

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

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

Alte Antwort

Dies ist tatsächlich ein nützlicheres Ergebnis als ein Zeichenoffset im Text des gesamten Dokuments: die startOffset Eigenschaft eines DOM-Bereichs (das ist das, was window.getSelection().getRangeAt() returns) ist ein Offset relativ zu seinem startContainer Eigenschaft (die übrigens nicht unbedingt immer ein Textknoten ist). Wenn Sie jedoch wirklich einen Zeichen-Offset benötigen, finden Sie hier eine Funktion, die dies ermöglicht.

Hier ist ein Beispiel aus dem Leben: 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;
}

18voto

Andrea Punkte 159

Dies ist ein sehr alter Beitrag, aber immer noch eines der ersten Suchergebnisse bei Google, also vielleicht noch nützlich. Dies funktioniert bei mir, um die richtige Position unter Berücksichtigung von html-Tags und Zeilenumbrüchen zu erhalten (getestet mit 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 die eigentliche HTML zu erhalten, und hängt das Dokumentfragment an ein temporäres Div an, um die HTML-Länge zu erhalten.

1voto

Antti Punkte 903

Wenn Sie ein Element einfügen möchten, können Sie dies folgendermaßen tun:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X