Question Position du curseur jQuery dans la zone de texte


Comment définir la position du curseur dans un champ de texte en utilisant jQuery? J'ai un champ de texte avec du contenu, et je veux que le curseur des utilisateurs soit positionné à un certain décalage quand ils se concentrent sur le champ. Le code devrait ressembler à ceci:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

À quoi ressemblerait l'implémentation de cette fonction setCursorPosition? Si vous aviez un champ de texte avec le contenu abcdefg, cet appel se traduirait par le positionnement du curseur comme suit: abcd ** | ** efg.

Java a une fonction similaire, setCaretPosition. Existe-t-il une méthode similaire pour le javascript?

Mise à jour: j'ai modifié le code de CMS pour travailler avec jQuery comme suit:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

418
2018-01-31 16:39


origine


Réponses:


J'ai deux fonctions:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

Ensuite, vous pouvez utiliser setCaretToPos comme ceci:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

Exemple en direct avec à la fois un textarea Et un input, montrant l'utilisation de jQuery:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

À partir de 2016, testé et fonctionnant sur Chrome, Firefox, IE11, même IE8 (voir ce dernier ici; Les extraits de pile ne prennent pas en charge IE8).


239
2018-01-31 16:56



Voici une solution jQuery:

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

Avec cela, vous pouvez faire

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

285
2018-05-08 18:17



Les solutions ici sont correctes à l'exception du code d'extension jQuery.

La fonction d'extension doit parcourir chaque élément sélectionné et retourner this pour soutenir le chaînage. Voici la  une version correcte:

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

36
2017-09-06 11:55



J'ai trouvé une solution qui fonctionne pour moi:

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

Maintenant, vous pouvez déplacer le focus à la fin de n'importe quel élément en appelant:

$(element).focusEnd();

21
2017-08-24 19:02



Cela a fonctionné pour moi sur Safari 5 sur Mac OSX, jQuery 1.4:

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

9
2017-08-26 15:51



J'utilise ceci: http://plugins.jquery.com/project/jCaret


6
2018-01-18 20:20



Définir le focus avant d'avoir inséré le texte dans la zone de texte ainsi?

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

6
2018-01-01 09:38



Je me rends compte que c'est un très vieux post, mais j'ai pensé que je devrais offrir une solution plus simple pour le mettre à jour en utilisant seulement jQuery.

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

Utilisation de ctrl-enter pour ajouter une nouvelle ligne (comme sur Facebook):

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

Je suis ouvert à la critique. Je vous remercie.

MISE À JOUR: Cette solution ne permet pas le fonctionnement normal du copier-coller (ie ctrl-c, ctrl-v), donc je devrai l'éditer dans le futur pour m'assurer que cette partie fonctionne à nouveau. Si vous avez une idée de comment faire, veuillez commenter ici, et je serai heureux de le tester. Merci.


6
2017-12-03 20:44



Dans IE pour déplacer le curseur sur une position, ce code suffit:

var range = elt.createTextRange();
range.move('character', pos);
range.select();

5
2018-05-14 13:12



Cela fonctionne pour moi en chrome

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

Apparemment, vous avez besoin d'un délai d'une microseconde ou plus, car généralement un utilisateur se concentre sur le champ de texte en cliquant sur une position dans le champ de texte (ou en cliquant sur l'onglet) que vous voulez remplacer, donc vous devez attendre que la position défini par l'utilisateur cliquez sur puis modifiez-le.


5
2018-06-27 23:16