Tengo esta función para enfocar un div contento y mover el cursor al final del texto, pero no funciona como se esperaba.

haga clic en el botón "Mover el cursor al final", la posición del cursor es 1 en lugar de la longitud div # foo. Pero si haces clic en el carácter "g" de "soy una cadena", la posición del cursor es 12

function moveCaretToEnd(nativeElement) {
        nativeElement.focus();
        if (window.getSelection) {
          if (typeof window.getSelection !== 'undefined' && typeof document.createRange !== 'undefined') {
            const range = document.createRange();
            range.selectNodeContents(nativeElement.firstChild);
            range.collapse(false);
            const sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
          }
        }
        updateCaretPos(window.getSelection().anchorOffset);
}

function updateCaretPos(pos){
   document.getElementById('caretpos').innerHTML = pos;
}
<div id="foo" contenteditable="true" onclick="updateCaretPos(window.getSelection().anchorOffset)" style="border: 1px solid grey">i'm a string</div>
<p>Caret position <div id="caretpos"></div></p>
<button onclick="moveCaretToEnd(document.getElementById('foo'))">Move caret to end</button>
1
ar099968 16 oct. 2018 a las 19:06

2 respuestas

La mejor respuesta

Pasas 'esto' a la función, pero 'esto' será el 'botón', no el div.

Pruebe este html en su lugar:

<button onclick="moveCaretToEnd(document.getElementById('foo'))">Move caret to end</button>

Editar :

Para seleccionar el textNode, puede intentar:

range.selectNodeContents(nativeElement.firstChild);
1
Poul Bak 16 oct. 2018 a las 16:33

Está intentando pasar el botón como elemento para que aparezca el símbolo de intercalación, le sugiero que haga lo siguiente:

function moveCaretToEnd(nativeElement) {
        // If nothing passed, choose an element by default
        nativeElement = nativeElement || document.getElementById('foo');
        nativeElement.focus();
        if (window.getSelection) {
          if (typeof window.getSelection !== 'undefined' && typeof document.createRange !== 'undefined') {
            const range = document.createRange();
            range.selectNodeContents(nativeElement);
            range.collapse(false);
            const sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
          }
        }
        updateCaretPos();
}

function updateCaretPos(){
   document.getElementById('caretpos').innerHTML = window.getSelection().anchorOffset;
}



moveCaretToEnd(document.getElementById('foo'));

Y en el lado HTML, agregué type="button" en el botón para que no se envíe:

<div id="foo" contenteditable="true" onclick="updateCaretPos()">click me</div>
<p>Caret position <div id="caretpos"></div></p>
<button type="button" onclick="moveCaretToEnd()">Move caret to end</button>
2
Nir Tzezana 16 oct. 2018 a las 16:19