2011-10-12 38 views
49

Tengo un área de texto y me gustaría saber si estoy en la última línea del área de texto o la primera línea en el área de texto con mi cursor con javascript.¿Cómo se obtiene la posición del cursor en un área de texto?

Pensé en tomar la posición del primer carácter de nueva línea y el último carácter de nueva línea y luego tomar la posición del cursor.

var firstNewline = $('#myTextarea').val().indexOf('\n'); 
var lastNewline = $('#myTextarea').val().lastIndexOf('\n'); 

var cursorPosition = ?????; 

if (cursorPosition < firstNewline) 
    // I am on first line. 
else if (cursorPosition > lastNewline) 
    // I am on last line. 
  • ¿Es posible tomar la posición del cursor en el área de texto?
  • ¿Tiene una mejor sugerencia para saber si estoy en la primera o última línea de un área de texto?

jQuery soluciones preferidas a menos que javascript sea tan simple o más simple.

Cualquier ayuda es muy apreciada.

+0

Ha visto la solución aquí: http://blog.vishalon.net/index .php/javascript-getting-and-setting-care-position-in-textarea/ –

+0

Esto arrojará un error, ya que las funciones 'indexOf' y lastIndexOf' no son métodos de la función val'. Debe usar esto (aunque no debe usar ese código): 'var firstNewline = String ($ (" # myTextarea "). Val()). IndexOf ('\ n');' – TricksfortheWeb

Respuesta

60

Si no hay una selección, puede usar las propiedades .selectionStart o .selectionEnd (sin selección son iguales).

var cursorPosition = $('#myTextarea').prop("selectionStart"); 

Tenga en cuenta que esto no es compatible con navegadores más antiguos, especialmente IE8-. Allí tendrás que trabajar con rangos de texto, pero es una completa frustración.

Creo que hay una biblioteca en algún lugar que está dedicada a obtener y establecer selecciones/posiciones del cursor en los elementos de entrada. No recuerdo su nombre, pero parece que hay docenas en artículos sobre este tema.

+0

Dang. ¿Hay alguna manera de hacer que esto funcione en IE8? Gracias por la solución. – Chev

+0

@Alex Ford: ahora veo que se ha respondido antes de hecho: http://stackoverflow.com/questions/2897155/get-caret-position-within-an-text-input-field. – pimvdb

+0

Tiene razón. Usé el plugin jquery que un respondedor dio sobre la pregunta que enlazó. Eso lo hizo. Perdón por el duplicado. – Chev

16

Aquí hay una función de navegador cruz que tengo en mi biblioteca estándar:

function getCursorPos(input) { 
    if ("selectionStart" in input && document.activeElement == input) { 
     return { 
      start: input.selectionStart, 
      end: input.selectionEnd 
     }; 
    } 
    else if (input.createTextRange) { 
     var sel = document.selection.createRange(); 
     if (sel.parentElement() === input) { 
      var rng = input.createTextRange(); 
      rng.moveToBookmark(sel.getBookmark()); 
      for (var len = 0; 
        rng.compareEndPoints("EndToStart", rng) > 0; 
        rng.moveEnd("character", -1)) { 
       len++; 
      } 
      rng.setEndPoint("StartToStart", input.createTextRange()); 
      for (var pos = { start: 0, end: len }; 
        rng.compareEndPoints("EndToStart", rng) > 0; 
        rng.moveEnd("character", -1)) { 
       pos.start++; 
       pos.end++; 
      } 
      return pos; 
     } 
    } 
    return -1; 
} 

utilizarlo en su código como este:

var cursorPosition = getCursorPos($('#myTextarea')[0]) 

Aquí es su función complementaria:

function setCursorPos(input, start, end) { 
    if (arguments.length < 3) end = start; 
    if ("selectionStart" in input) { 
     setTimeout(function() { 
      input.selectionStart = start; 
      input.selectionEnd = end; 
     }, 1); 
    } 
    else if (input.createTextRange) { 
     var rng = input.createTextRange(); 
     rng.moveStart("character", start); 
     rng.collapse(); 
     rng.moveEnd("character", end - start); 
     rng.select(); 
    } 
} 

http://jsfiddle.net/gilly3/6SUN8/

+0

No funciona con saltos de línea principales/finales en IE <9. –

+0

@TimDown - Tiene razón. Ahora me doy cuenta de que la versión que pegué aquí, he estado utilizando para controles '' exclusivamente. He editado mi respuesta para usar una versión que también funciona para los controles '