javascript jquery contenteditable caret cursor-position

javascript - Cómo establecer la posición de cursor(cursor) en el elemento contenteditable(div)?



jquery caret (4)

En la mayoría de los navegadores, necesita los objetos de Range y Selection . Usted especifica cada uno de los límites de selección como un nodo y un desplazamiento dentro de ese nodo. Por ejemplo, para configurar el cursor al quinto carácter de la segunda línea de texto, haría lo siguiente:

var el = document.getElementById("editable"); var range = document.createRange(); var sel = window.getSelection(); range.setStart(el.childNodes[2], 5); range.collapse(true); sel.removeAllRanges(); sel.addRange(range);

IE <9 funciona de manera completamente diferente. Si necesita admitir estos navegadores, necesitará un código diferente.

Ejemplo jsFiddle: http://jsfiddle.net/timdown/vXnCM/

Tengo este simple HTML como un ejemplo:

<div id="editable" contenteditable="true"> text text text<br> text text text<br> text text text<br> </div> <button id="button">focus</button>

Quiero algo simple: cuando hago clic en el botón, quiero colocar el cursor (cursor) en un lugar específico en el div editable. Desde la búsqueda en la web, tengo este JS adjunto al botón, pero no funciona (FF, Chrome):

var range = document.createRange(); var myDiv = document.getElementById("editable"); range.setStart(myDiv, 5); range.setEnd(myDiv, 5);

¿Es posible establecer una posición de cuidado manual así?


Es muy difícil configurar el cursor en la posición correcta cuando tiene un elemento de avance como (p) (span), etc. El objetivo es obtener (texto del objeto):

<div id="editable" contenteditable="true">dddddddddddddddddddddddddddd<p>dd</p>psss<p>dd</p><p>dd</p> <p>text text text</p> </div> <p id=''we''></p> <button onclick="set_mouse()">focus</button> <script> function set_mouse() { var as = document.getElementById("editable"); el=as.childNodes[1].childNodes[0];//goal is to get (''we'') id to write (object Text) because it work only in object text var range = document.createRange(); var sel = window.getSelection(); range.setStart(el, 1); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); document.getElementById("we").innerHTML=el;// see out put of we id } </script>


La mayoría de las respuestas que encuentras sobre el posicionamiento del cursor contenteditable son bastante simplistas, ya que solo atienden las entradas con texto sencillo y corriente. Una vez que utiliza los elementos html dentro del contenedor, el texto ingresado se divide en nodos y se distribuye generosamente a través de una estructura de árbol.

Para establecer la posición del cursor, tengo esta función que gira alrededor de todos los nodos de texto secundarios dentro del nodo suministrado y establece un rango desde el inicio del nodo inicial hasta el carácter chars.count :

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

Luego llamo a la rutina con esta función:

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

El rango.collapse (falso) establece el cursor al final del rango. Lo probé con las últimas versiones de Chrome, IE, Mozilla y Opera, y todos funcionan bien.

PD. Si alguien está interesado, obtengo la posición actual del cursor usando este código:

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

El código hace lo contrario de la función establecida: obtiene el actual window.getSelection (). FocusNode y focusOffset y cuenta hacia atrás todos los caracteres de texto encontrados hasta que llega a un nodo padre con id de containerId. La función isChildOf simplemente comprueba antes de ejecutar que el nodo suministrado es en realidad un elemento secundario del parentId proporcionado.

El código debería funcionar correctamente sin cambios, pero acabo de tomarlo de un plugin de jQuery que he desarrollado, así que he pirateado un par de esto . ¡Avíseme si algo no funciona!


Si no quieres usar jQuery, puedes probar este enfoque:

public setCaretPosition() { const editableDiv = document.getElementById(''contenteditablediv''); const lastLine = this.input.nativeElement.innerHTML.replace(/.*?(<br>)/g, ''''); const selection = window.getSelection(); selection.collapse(editableDiv.childNodes[editableDiv.childNodes.length - 1], lastLine.length); }

editableDiv usted elemento editable, no se olvide de establecer una id para ello. Luego necesitas sacar tu innerHTML del elemento y cortar todas las líneas de freno. Y simplemente establece el colapso con los siguientes argumentos.