Die meisten Antworten, die Sie zur inhaltsbearbeitbaren Cursorpositionierung finden, sind ziemlich simpel, da sie nur Eingaben mit einfachem Vanille-Text ermöglichen. Sobald Sie HTML-Elemente im Container verwenden, wird der eingegebene Text in Knoten aufgeteilt und großzügig über eine Baumstruktur verteilt.
Um die Cursorposition zu setzen, habe ich diese Funktion, die alle untergeordneten Textknoten innerhalb des angegebenen Knotens umkreist und einen Bereich vom Anfang des Anfangsknotens bis zum Zeichen chars.count festlegt :
function createRange(node, chars, range) {
if (!range) {
range = document.createRange()
range.selectNode(node);
range.setStart(node, 0);
}
if (chars.count === 0) {
range.setEnd(node, chars.count);
} else if (node && chars.count >0) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.length < chars.count) {
chars.count -= node.textContent.length;
} else {
range.setEnd(node, chars.count);
chars.count = 0;
}
} else {
for (var lp = 0; lp < node.childNodes.length; lp++) {
range = createRange(node.childNodes[lp], chars, range);
if (chars.count === 0) {
break;
}
}
}
}
return range;
};
Ich rufe dann die Routine mit dieser Funktion auf:
function setCurrentCursorPosition(chars) {
if (chars >= 0) {
var selection = window.getSelection();
range = createRange(document.getElementById("test").parentNode, { count: chars });
if (range) {
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
};
Der range.collapse (false) setzt den Cursor auf das Ende des Bereichs. Ich habe es mit den neuesten Versionen von Chrome, IE, Mozilla und Opera getestet und alle funktionieren einwandfrei.
PS. Wenn jemand interessiert ist, erhalte ich die aktuelle Cursorposition mit diesem Code:
function isChildOf(node, parentId) {
while (node !== null) {
if (node.id === parentId) {
return true;
}
node = node.parentNode;
}
return false;
};
function getCurrentCursorPosition(parentId) {
var selection = window.getSelection(),
charCount = -1,
node;
if (selection.focusNode) {
if (isChildOf(selection.focusNode, parentId)) {
node = selection.focusNode;
charCount = selection.focusOffset;
while (node) {
if (node.id === parentId) {
break;
}
if (node.previousSibling) {
node = node.previousSibling;
charCount += node.textContent.length;
} else {
node = node.parentNode;
if (node === null) {
break
}
}
}
}
}
return charCount;
};
Der Code macht das Gegenteil der Set-Funktion - er ruft das aktuelle window.getSelection (). FocusNode und focusOffset ab und zählt alle gefundenen Textzeichen rückwärts, bis er auf einen übergeordneten Knoten mit der ID containerId trifft. Die Funktion isChildOf prüft vor dem Ausführen, ob der angegebene Knoten tatsächlich ein untergeordnetes Element der angegebenen übergeordneten ID ist .
Der Code sollte ohne Änderung direkt funktionieren, aber ich habe ihn gerade aus einem von mir entwickelten jQuery-Plugin übernommen und ein paar davon gehackt - lassen Sie mich wissen, wenn etwas nicht funktioniert!