javascript wysiwyg contenteditable getselection

javascript - Obtener la posición de cursor(cursor) en el contenido Área editable que contiene contenido HTML



wysiwyg contenteditable (3)

ACTUALIZAR

He escrito una versión más simple de esto que también funciona en IE <9:

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

Vieja respuesta

Este es en realidad un resultado más útil que un desplazamiento de caracteres en el texto del documento completo: la propiedad startOffset de un rango DOM (que es lo que window.getSelection().getRangeAt() ) es un desplazamiento relativo a su propiedad startContainer ( que no es necesariamente siempre un nodo de texto, por cierto). Sin embargo, si realmente quieres una compensación de caracteres, aquí hay una función que lo hará.

Aquí hay un ejemplo en vivo: http://jsfiddle.net/timdown/2YcaX/

Aquí está la función:

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; }

Tengo contenido Elemento editable (puede ser p, div, ...) y me gustaría obtener la posición de cursor (cursor) en él. Normalmente puedo lograrlo con este código:

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

Esto funciona bien mientras que el elemento contiene solo texto. Pero cuando el elemento contiene algún formato HTML, la posición devuelta es relativa a la posición de intercalación dentro del elemento HTML incluido.

Supongamos que el contenido del elemento contentEditable es este:

AB<b>CD</b>EF

Si el cursor está dentro de <b></b> , digamos entre C y D, la posición devuelta con el código anterior es 1 en lugar de 3 (contada desde el comienzo del contenido del contenido del elemento editable)

¿Alguien puede encontrar una solución a esto?


Esta es una publicación muy antigua, pero sigue siendo uno de los primeros resultados de búsqueda en Google, por lo que puede ser útil. Esto me ayuda a posicionarme correctamente teniendo en cuenta las etiquetas html y las nuevas líneas (probadas en 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; }

Utiliza la funcionalidad cloneContents para obtener el html real y agrega el documentfragment a un div temporal para obtener la longitud html.


Si desea insertar un elemento, puede intentar hacer algo como esto:

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