Imposta la posizione del cursore sulla tastiera nella casella di testo HTML


173

Qualcuno sa come spostare il cursore della tastiera in una casella di testo in una posizione particolare?

Ad esempio, se una casella di testo (ad esempio un elemento di input, non un'area di testo) contiene 50 caratteri e voglio posizionare il cursore prima del carattere 20, come potrei procedere?

Ciò si differenzia da questa domanda: jQuery Imposta posizione cursore nell'area di testo , che richiede jQuery.

Risposte:


205

Estratto dalla posizione del cursore della tastiera Impostazione di Josh Stodola in una casella di testo o TextArea con Javascript

Una funzione generica che ti permetterà di inserire il cursore in qualsiasi posizione di una casella di testo o area di testo che desideri:

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 previsto è l'ID dell'elemento su cui si desidera inserire il cursore della tastiera. Se l'elemento non può essere trovato, non succederà nulla (ovviamente). Il secondo parametro è l'indice di positività del punto di inserimento. 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 cursore della 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 dell'utilizzo della funzione precedente per forzare il cursore della tastiera a saltare alla fine di tutte le textareas sulla pagina quando ricevono lo stato attivo:

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 faccio clic sulla casella di testo effettiva, mi aspetto che la posizione del punto di inserimento sia all'inizio. Dai
elad.chen il

La funzione setCaretPosition funziona perfettamente. La tua funzione addActionHandler, tuttavia, no. Ma anche senza quello, non riuscivo a far muovere il cursore sulla messa 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

Funziona con IE9, FF25, ma non con Chrome 30. Meglio di niente!
Umber Ferrule

Ho elem.value = elem.value.replace(/^9/g,'+79')nel codice. Sul cursore OperaMINI dopo +. questa funzione non aiuta
eri il

52

Il link nella risposta è interrotto, questo dovrebbe funzionare (tutti i crediti vanno su blog.vishalon.net ):

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

Nel caso in cui il codice si perda di nuovo, ecco 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();
 }
}

1
+1 per le funzioni di base, anche se è necessario apportare alcune modifiche . Il numero di righe deve essere sottratto da "pos", quando si utilizza il metodo range.
Rob W,

36

Poiché in realtà avevo davvero bisogno di questa soluzione e la tipica soluzione di base ( focalizzare l'input - quindi impostare il valore uguale a se stessa ) non funziona su più browser , ho trascorso un po 'di tempo a modificare e modificare tutto per farlo funzionare. Basandomi sul codice di @ kd7 , ecco cosa ho escogitato.

Godere! Funziona in IE6 +, Firefox, Chrome, Safari, Opera

Tecnica di posizionamento del cursore cross-browser (esempio: spostamento del cursore su 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 sono fondamentalmente il setCaretPosition di @ kd7 , con il più grande tweak che è if (el.selectionStart || el.selectionStart === 0), in firefox la selezioneStart inizia da 0 , che in booleano ovviamente si sta trasformando in False, quindi si stava rompendo lì.

In Chrome il problema più grande era che il solo dare non .focus()era abbastanza (continuava a selezionare TUTTO il testo!) Quindi, abbiamo impostato il valore di se stesso, su se stesso el.value = el.value;prima di chiamare la nostra funzione, e ora ha una comprensione e una posizione con il input per usare 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;
            }
        }
    }
}

@mcpDESIGNS Sto provando a usare questa funzione quando ci si concentra su un input di testo, ma non sto arrivando da nessuna parte, potresti aiutarmi ad applicare questa funzione usando javascript puro?
elad.chen

@ elad.chen Stai cercando di posizionarli alla fine della casella di testo non appena si concentrano su di esso?
Mark Pieszak - Trilon.io

@mcpDESIGNS Voglio posizionare il cursore all'inizio del campo non appena l'elemento viene focalizzato. Vedi il violino: jsfiddle.net/KuLTU/3
elad.chen

@ elad.chen Ci scusiamo per la folle risposta in ritardo! Basta modificare l'evento in .onclickanziché .onfocusall'interno della funzione search_field_focus
Mark Pieszak - Trilon.io

2
el.value = el.value; [...] if(el !== null)- Vorrei scambiare queste due righe. Se elè null, el.value = el.valuefallirà, quindi quella riga dovrebbe trovarsi all'interno di if.
BackSlash

21

Ho modificato un po 'la risposta di kd7 perché elem.selectionStart valuterà falso quando casualmente selectionStart è 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);
        }
    }
}

5

Ho trovato un modo semplice per risolvere questo problema, testato in IE e Chrome:

function setCaret(elemId, caret)
 {
   var elem = document.getElementById(elemId);
   elem.setSelectionRange(caret, caret);
 }

Passa l'ID della casella di testo e la posizione del cursore a questa funzione.


3

Se devi mettere a fuoco alcune caselle di testo e il tuo unico problema è che l'intero testo viene evidenziato mentre vuoi che il punto di inserimento sia alla fine, quindi in quel caso specifico, puoi usare questo trucco per impostare il valore della casella di testo su se stesso dopo lo stato attivo:

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

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>

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

Uncaught TypeError: Object [object HTMLInputElement] non ha alcun metodo 'startWith'
bobpaul

1
@bobpaul: tIDdovrebbe essere l'id dell'elemento, non l'oggetto dell'elemento stesso. Se stai passando l'oggetto element, puoi semplicemente rimuovere le 2 prime righe in questo metodo e funzionerà.
timore

2

Vorrei correggere le condizioni come di seguito:

function setCaretPosition(elemId, caretPos)
{
 var elem = document.getElementById(elemId);
 if (elem)
 {
  if (typeof elem.createTextRange != 'undefined')
  {
   var range = elem.createTextRange();
   range.move('character', caretPos);
   range.select();
  }
  else
  {
   if (typeof elem.selectionStart != 'undefined')
    elem.selectionStart = caretPos;
   elem.focus();
  }
 }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.