web-dev-qa-db-fra.com

Définir la position du clavier dans la zone de texte html

Est-ce que quelqu'un sait comment déplacer le curseur de clavier dans une zone de texte à une position particulière?

Par exemple, si une zone de texte (par exemple, un élément d'entrée, pas une zone de texte) contient 50 caractères et que je souhaite positionner le curseur avant le caractère 20, comment procéder?

Ceci est différent de la question suivante: Position du curseur dans la zone de texte définie par jQuery , ce qui nécessite jQuery.

159
jonhobbs

Extrait de Josh Stodola Réglage de la position du caret au clavier dans une zone de texte ou une zone de texte avec Javascript

Une fonction générique qui vous permettra d’insérer le curseur à n’importe quelle position d’une zone de texte ou d’une zone de texte de votre choix:

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

Le premier paramètre attendu est l'ID de l'élément sur lequel vous souhaitez insérer le curseur. Si l'élément est introuvable, rien ne se passera (évidemment). Le deuxième paramètre est l'indice de position de caret. Zéro mettra le curseur au clavier au début. Si vous transmettez un nombre supérieur au nombre de caractères dans la valeur des éléments, le curseur inséré à la fin du curseur.

Testé sur IE6 et ultérieur, Firefox 2, Opera 8, Netscape 9, SeaMonkey et Safari. Malheureusement sur Safari, cela ne fonctionne pas en combinaison avec l'événement onfocus).

Un exemple d'utilisation de la fonction ci-dessus pour forcer le curseur du clavier à accéder à la fin de toutes les zones de texte de la page lorsqu'ils reçoivent le focus:

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);
183
kd7

Le lien dans la réponse est cassé, celui-ci devrait fonctionner (tous les crédits vont à blog.vishalon.net ):

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

Au cas où le code serait à nouveau perdu, voici les deux fonctions principales:

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();
 }
}
50
eternal

Étant donné que j’avais réellement besoin de cette solution et que la solution de base typique () concentre l’entrée - définissez ensuite la valeur sur elle-même ) ne fonctionne pas. travail multi-navigateur , j’ai passé du temps à peaufiner et à tout éditer pour le faire fonctionner. S'appuyant sur le code de @ kd7 , voici ce que j'ai trouvé.

Profitez-en! Fonctionne dans IE6 +, Firefox, Chrome, Safari, Opera

Technique de positionnement du caret inter-navigateurs (exemple: déplacer le curseur vers la fin)

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

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

La viande et les pommes de terre sont fondamentalement la position setCaretPosition de @ kd7 , avec le plus gros Tweak étant if (el.selectionStart || el.selectionStart === 0), dans firefox la sélection commence à partir de 0 , ce qui en booléen est en train de se transformer en Faux, donc il se cassait là.

Dans chrome, le plus gros problème était que le simple fait de lui donner .focus() n'était pas suffisant (il continuait de sélectionner TOUT le texte!). Par conséquent, nous définissons la valeur de lui-même, el.value = el.value; avant d'appeler notre fonction, et maintenant elle a une saisie et une position avec l'entrée à utiliser 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;
            }
        }
    }
}
33

J'ai légèrement ajusté la réponse de kd7 car elem.selectionStart sera évalué à false lorsque selectionStart a la valeur 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);
        }
    }
}
21
Johannes Ewald

Si vous avez besoin de vous concentrer sur une zone de texte et que votre seul problème est que tout le texte est mis en surbrillance alors que vous voulez que le curseur soit à la fin, vous pouvez utiliser cette astuce pour définir la valeur de la zone de texte après le focus:

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

Je fixerais les conditions comme ci-dessous:

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();
  }
 }
}
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
DIpak
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); }
2
Keith Cromm

J'ai trouvé un moyen simple de résoudre ce problème, testé dans IE et Chrome 100%

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

Transmet l'identifiant de la zone de texte et la position du curseur à cette fonction

0
Iam_NSA