2009-02-04 8 views
133

Qualcuno sa come spostare il cursore della tastiera in una casella di testo in una posizione particolare?Imposta la posizione del cursore di tastiera nella casella di testo HTML

Ad esempio, se una casella di testo (ad esempio, elemento di input, non area di testo) contiene 50 caratteri e voglio posizionare il punto di inserimento prima del carattere 20, come dovrei farlo?

Questo è in differenziazione da questa domanda: jQuery Set Cursor Position in Text Area, che richiede jQuery.

+28

questo non è un duplicato, uno richiede jQuery l'altro non vuol – Isaac

+2

@Isaac ho votato a riaprire questo. Tieni presente che SO ha un sacco di piccoli mod che non si preoccupano di altro che di un editing cieco per scopi egoistici. – John

risposta

153

Tratto da Setting keyboard caret Position in a Textbox or TextArea with Javascript

una generica funzione di Josh Stodola che vi permetterà di inserire il punto di inserimento in qualsiasi posizione di una casella di testo o di textarea che si desidera:

function setCaretPosition(elemId, caretPos) { 
    var elem = document.getElementById(elemId); 

    if(elem != null) { 
     if(elem.createTextRange) { 
      var range = elem.createTextRange(); 
      range.move('character', caretPos); 
      range.select(); 
     } 
     else { 
      if(elem.selectionStart) { 
       elem.focus(); 
       elem.setSelectionRange(caretPos, caretPos); 
      } 
      else 
       elem.focus(); 
     } 
    } 
} 

Il primo parametro atteso è l'ID dell'elemento su cui desideri inserire il cursore della tastiera. Se l'elemento non può essere trovato, non accadrà nulla (ovviamente). Il secondo parametro è l'indice di positività al caret. Zero metterà il cursore della tastiera all'inizio. Se passi un numero maggiore del numero di caratteri nel valore degli elementi, alla fine verrà inserito il carattere di tastiera.

Testato su IE6 e versioni successive, Firefox 2, Opera 8, Netscape 9, SeaMonkey e Safari. Sfortunatamente su Safari non funziona in combinazione con l'evento onfocus).

Un esempio di utilizzo della funzione di cui sopra per forzare il cursore della tastiera per saltare alla fine di tutte le aree di testo nella pagina quando ricevono attenzione:

function addLoadEvent(func) { 
    if(typeof window.onload != 'function') { 
     window.onload = func; 
    } 
    else { 
     if(func) { 
      var oldLoad = window.onload; 

      window.onload = function() { 
       if(oldLoad) 
         oldLoad(); 

       func(); 
      } 
     } 
    } 
} 

// The setCaretPosition function belongs right here! 

function setTextAreasOnFocus() { 
/*** 
* This function will force the keyboard caret to be positioned 
* at the end of all textareas when they receive focus. 
*/ 
    var textAreas = document.getElementsByTagName('textarea'); 

    for(var i = 0; i < textAreas.length; i++) { 
     textAreas[i].onfocus = function() { 
      setCaretPosition(this.id, this.value.length); 
     } 
    } 

    textAreas = null; 
} 

addLoadEvent(setTextAreasOnFocus); 
+4

'if (elem.selectionStart)' si interrompe quando selectionStart è 0 come indicato anche dalla risposta di jhnns. – mpartel

+1

Questo non funziona per me. Quando clicco sulla casella di testo effettiva, mi aspetto che la posizione del punto di inserimento sia all'inizio. Dai un'occhiata al mio violino http://jsfiddle.net/khx2w/ –

+0

La funzione setCaretPosition funziona perfettamente. La tua funzione addActionHandler, tuttavia, non lo fa. Ma anche senza quello, non ho potuto ottenere il cursore per spostare a fuoco. Molto probabilmente, è perché il browser imposta la posizione del cursore stessa in base alla posizione del clic. Non sembra esserci un modo per aggirare ciò che posso dire, ma potrei sbagliarmi completamente. – GJK

44

Il link nella risposta è rotto, questo si dovrebbe lavoro (tutti i crediti vanno a blog.vishalon.net):

http://snipplr.com/view/5144/getset-cursor-in-html-textarea/

Se il codice si perde di nuovo, qui le due funzioni principali:

function doGetCaretPosition(ctrl) 
{ 
var CaretPos = 0; 

if (ctrl.selectionStart || ctrl.selectionStart == 0) 
{// Standard. 
    CaretPos = ctrl.selectionStart; 
} 
else if (document.selection) 
{// Legacy IE 
    ctrl.focus(); 
    var Sel = document.selection.createRange(); 
    Sel.moveStart ('character', -ctrl.value.length); 
    CaretPos = Sel.text.length; 
} 

return (CaretPos); 
} 


function setCaretPosition(ctrl,pos) 
{ 
if (ctrl.setSelectionRange) 
{ 
    ctrl.focus(); 
    ctrl.setSelectionRange(pos,pos); 
} 
else if (ctrl.createTextRange) 
{ 
    var range = ctrl.createTextRange(); 
    range.collapse(true); 
    range.moveEnd('character', pos); 
    range.moveStart('character', pos); 
    range.select(); 
} 
} 
+0

+1 per le funzioni di base, anche se ** alcune regolazioni devono essere fatte **. Il numero di linee deve essere sottratto da "pos", quando si utilizza il metodo dell'intervallo. –

2
function SetCaretEnd(tID) { 
    tID += ""; 
    if (!tID.startsWith("#")) { tID = "#" + tID; } 
    $(tID).focus(); 
    var t = $(tID).val(); 
    if (t.length == 0) { return; } 
    $(tID).val(""); 
    $(tID).val(t); 
    $(tID).scrollTop($(tID)[0].scrollHeight); } 
+0

Unchaught TypeError: Object [object HTMLInputElement] non ha alcun metodo 'startsWith' – bobpaul

+1

@bobpaul: 'tID' dovrebbe essere l'id dell'elemento, non l'oggetto elemento stesso. Se si passa l'oggetto elemento, è possibile rimuovere solo le prime due righe in questo metodo e funzionerà. – awe

2
<!DOCTYPE html> 
<html> 
<head> 
<title>set caret position</title> 
<script type="application/javascript"> 
//<![CDATA[ 
window.onload = function() 
{ 
setCaret(document.getElementById('input1'), 13, 13) 
} 

function setCaret(el, st, end) 
{ 
if (el.setSelectionRange) 
{ 
    el.focus(); 
    el.setSelectionRange(st, end); 
} 
else 
{ 
    if (el.createTextRange) 
    { 
    range = el.createTextRange(); 
    range.collapse(true); 
    range.moveEnd('character', end); 
    range.moveStart('character', st); 
    range.select(); 
    } 
} 
} 
//]]> 
</script> 
</head> 
<body> 

<textarea id="input1" name="input1" rows="10" cols="30">Happy kittens dancing</textarea> 

<p>&nbsp;</p> 

</body> 
</html> 
20

Ho modificato la risposta di KD7 un po 'perché elem.selectionStart valuterà false quando il selectionStart per inciso è 0.

function setCaretPosition(elem, caretPos) { 
    var range; 

    if (elem.createTextRange) { 
     range = elem.createTextRange(); 
     range.move('character', caretPos); 
     range.select(); 
    } else { 
     elem.focus(); 
     if (elem.selectionStart !== undefined) { 
      elem.setSelectionRange(caretPos, caretPos); 
     } 
    } 
} 
28

Dal momento che in realtà davvero bisogno di questo soluzione standard e la soluzione di base tipica (mette a fuoco l'input, quindi imposta il valore uguale a) non funziona nel cross-browser, ho dedicato un po 'di tempo a modificare e modificare tutto per farlo funzionare. Basandosi sul codice @kd7 ecco cosa mi è venuto in mente.

Divertiti!Lavori in IE6 +, Firefox, Chrome, Safari, Opera

Cross-browser caret positioning technique (example: moving the cursor to the END)

// ** USEAGE ** (returns a boolean true/false if it worked or not) 
// Parameters (Id_of_element, caretPosition_you_want) 

setCaretPosition('IDHERE', 10); // example 

La carne e le patate è fondamentalmente @KD7 s' setCaretPosition, con la più grande Tweak essendo if (el.selectionStart || el.selectionStart === 0), in Firefox la selectionStart è a partire da , che in booleano ovviamente si sta trasformando in False, quindi si è interrotto lì.

In Chrome il più grande problema era che solo dando .focus() non è stato sufficiente (ha mantenuto selezionando tutto il testo!) Quindi, abbiamo impostato il valore di per sé, a sé el.value = el.value; prima di chiamare la nostra funzione, ed ora ha una presa & posizione con l'input per utilizzare selectionStart.

function setCaretPosition(elemId, caretPos) { 
    var el = document.getElementById(elemId); 

    el.value = el.value; 
    //^this is used to not only get "focus", but 
    // to make sure we don't have it everything -selected- 
    // (it causes an issue in chrome, and having it doesn't hurt any other browser) 

    if (el !== null) { 

     if (el.createTextRange) { 
      var range = el.createTextRange(); 
      range.move('character', caretPos); 
      range.select(); 
      return true; 
     } 

     else { 
      // (el.selectionStart === 0 added for Firefox bug) 
      if (el.selectionStart || el.selectionStart === 0) { 
       el.focus(); 
       el.setSelectionRange(caretPos, caretPos); 
       return true; 
      } 

      else { // fail city, fortunately this never happens (as far as I've tested) :) 
       el.focus(); 
       return false; 
      } 
     } 
    } 
} 
+0

Grazie mille :) –

+0

In qualsiasi momento, contento che stia diventando utile altrove! @Mr_Green –

+0

@mcpDESIGNS Sto provando a utilizzare questa funzione quando viene eseguito un focus su un input di testo, ma non sto andando da nessuna parte, potresti aiutarci con l'applicazione di questa funzione usando puro javascript? –

3

Se è necessario concentrarsi un po 'di testo e il vostro unico problema è che l'intero testo viene evidenziato che, si desidera che il punto di inserimento di essere alla fine, allora in quel caso specifico, è possibile utilizzare questo trucco di impostare il valore casella di testo a se stesso dopo fuoco:

$("#myinputfield").focus().val($("#myinputfield").val());