172 votes

Insertion d'un texte à l'endroit où se trouve le curseur à l'aide de Javascript/jquery

J'ai une page contenant de nombreuses zones de texte. Lorsque quelqu'un clique sur un lien, je veux qu'un mot ou deux soient insérés à l'endroit où se trouve le curseur, ou ajoutés à la zone de texte qui a le focus.

Par exemple, si le curseur/focus est sur une zone de texte indiquant "apple" et qu'il clique sur un lien indiquant "[email]", je veux que la zone de texte indique "apple bob@example.com".

Comment puis-je faire cela ? Est-ce même possible, car que se passe-t-il si le focus est sur un élément radio/dropdown/non textbox ? Peut-on se souvenir de la dernière zone de texte sur laquelle on a mis l'accent ?

0 votes

Je suppose que c'est possible parce que c'est la base des éditeurs de WYSISYG, comment le faire, je ne sais pas.

0 votes

0 votes

Merci d'avoir posé cette question... maintenant je peux insérer "[version]" au curseur avec mon extension Chrome !

242voto

George Claghorn Points 6665

Utilisez ceci, de ici :

function insertAtCaret(areaId, text) {
  var txtarea = document.getElementById(areaId);
  if (!txtarea) {
    return;
  }

  var scrollPos = txtarea.scrollTop;
  var strPos = 0;
  var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
    "ff" : (document.selection ? "ie" : false));
  if (br == "ie") {
    txtarea.focus();
    var range = document.selection.createRange();
    range.moveStart('character', -txtarea.value.length);
    strPos = range.text.length;
  } else if (br == "ff") {
    strPos = txtarea.selectionStart;
  }

  var front = (txtarea.value).substring(0, strPos);
  var back = (txtarea.value).substring(strPos, txtarea.value.length);
  txtarea.value = front + text + back;
  strPos = strPos + text.length;
  if (br == "ie") {
    txtarea.focus();
    var ieRange = document.selection.createRange();
    ieRange.moveStart('character', -txtarea.value.length);
    ieRange.moveStart('character', strPos);
    ieRange.moveEnd('character', 0);
    ieRange.select();
  } else if (br == "ff") {
    txtarea.selectionStart = strPos;
    txtarea.selectionEnd = strPos;
    txtarea.focus();
  }

  txtarea.scrollTop = scrollPos;
}

<textarea id="textareaid"></textarea>
<a href="#" onclick="insertAtCaret('textareaid', 'text to insert');return false;">Click Here to Insert</a>

7 votes

Cela fonctionne très bien, mais il ne gère pas le remplacement du texte sélectionné comme le font tous les éditeurs de texte. Cela n'est peut-être pas nécessaire pour la question initiale de l'auteur, mais si vous en avez besoin, vous pouvez simplement remplacer "strPos" par "txtArea.selectionEnd". Ma réponse ci-dessous montre cela, ainsi que la suppression du code de détection du navigateur, si vous n'avez pas besoin de prendre en charge les anciennes versions d'IE.

0 votes

Existe-t-il un moyen de sélectionner tous les éléments avec areaId ?

1 votes

Vous pouvez réaliser la suppression automatique du texte sélectionné en insérant une fonction comme celle-ci. function deleteTxt() { var ele = document.getElementById('yourTextarea'); var text = ele.value; text = text.slice(0, ele.selectionStart) + text.slice(ele.selectionEnd); ele.value = text; return text; }

158voto

quik_silv Points 388

Peut-être qu'une version plus courte, serait plus facile à comprendre ?

    jQuery("#btn").on('click', function() {
        var $txt = jQuery("#txt");
        var caretPos = $txt[0].selectionStart;
        var textAreaTxt = $txt.val();
        var txtToAdd = "stuff";
        $txt.val(textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos) );
    });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<textarea id="txt" rows="15" cols="70">There is some text here.</textarea>
<input type="button" id="btn" value="OK" />

J'ai écrit ceci en réponse à Comment ajouter un texte à une zone de texte à partir de la position actuelle du pointeur avec jquery ?

12 votes

Vous pouvez également rétablir la position du curseur après avoir modifié la valeur avec : document.getElementById("txt").selectionStart = caretPos + txtToAdd.length .

1 votes

Ça a marché pour moi, merci. Pour info, la propriété "selectionStart" n'existe pas dans le sélecteur jquery $("#"). Vous devez passer par document.getElementById().

1 votes

jsfiddle.net/NaHTw/802 est votre solution avec un petit plus ajouté pour remplacer la zone sélectionnée par ce qui est collé.

23voto

Collin Anderson Points 952

Le code ci-dessus n'a pas fonctionné pour moi dans IE. Voici un code basé sur cette réponse .

J'ai sorti le getElementById afin que je puisse référencer l'élément d'une manière différente.

function insertAtCaret(element, text) {
  if (document.selection) {
    element.focus();
    var sel = document.selection.createRange();
    sel.text = text;
    element.focus();
  } else if (element.selectionStart || element.selectionStart === 0) {
    var startPos = element.selectionStart;
    var endPos = element.selectionEnd;
    var scrollTop = element.scrollTop;
    element.value = element.value.substring(0, startPos) +
      text + element.value.substring(endPos, element.value.length);
    element.focus();
    element.selectionStart = startPos + text.length;
    element.selectionEnd = startPos + text.length;
    element.scrollTop = scrollTop;
  } else {
    element.value += text;
    element.focus();
  }
}

input{width:100px}
label{display:block;margin:10px 0}

<label for="in2copy">Copy text from: <input id="in2copy" type="text" value="x"></label>
<label for="in2ins">Element to insert: <input id="in2ins" type="text" value="1,2,3" autofocus></label>
<button onclick="insertAtCaret(document.getElementById('in2ins'),document.getElementById('in2copy').value)">Insert</button>

EDIT : Ajout d'un extrait d'exécution, jQuery n'est pas utilisé .

0 votes

Element est-il un objet jquery ou non ? element.value et element.focus() ne peuvent pas fonctionner tous les deux...

7 votes

element.focus() est une méthode JavaScript légitime sur DOMElements : w3schools.com/jsref/met_html_focus.asp

1 votes

La meilleure idée est d'abandonner la compatibilité avec IE.

4voto

Comment insérer du texte à la position actuelle du curseur d'une TextBox grâce à JQuery et JavaScript.

Processus

  1. Trouver la position actuelle du curseur
  2. Obtenir le texte à copier
  3. Placez le texte là-bas
  4. Mettre à jour la position du curseur

Ici, j'ai 2 TextBoxes et un bouton. Je dois cliquer sur une certaine position dans une zone de texte, puis cliquer sur le bouton pour coller le texte de l'autre zone de texte à la position de la zone de texte précédente. l'autre zone de texte à la position de la zone de texte précédente.

Le principal problème ici est d'obtenir la position actuelle du curseur où nous allons coller le texte.

//Textbox on which to be pasted
<input type="text" id="txtOnWhichToBePasted" />

//Textbox from where to be pasted
<input type="text" id="txtFromWhichToBePasted" />

//Button on which click the text to be pasted
<input type="button" id="btnInsert" value="Insert"/>

<script type="text/javascript">

$(document).ready(function () {
    $('#btnInsert').bind('click', function () {
            var TextToBePasted = $('#txtFromWhichToBePasted').value;
            var ControlOnWhichToBePasted = $('#txtOnWhichToBePasted');

            //Paste the Text
            PasteTag(ControlOnWhichToBePasted, TextToBePasted);
        });
    });

//Function Pasting The Text
function PasteTag(ControlOnWhichToBePasted,TextToBePasted) {
    //Get the position where to be paste

    var CaretPos = 0;
    // IE Support
    if (document.selection) {

        ControlOnWhichToBePasted.focus();
        var Sel = document.selection.createRange();

        Sel.moveStart('character', -ctrl.value.length);

        CaretPos = Sel.text.length;
    }
    // Firefox support
    else if (ControlOnWhichToBePasted.selectionStart || ControlOnWhichToBePasted.selectionStart == '0')
        CaretPos = ControlOnWhichToBePasted.selectionStart;

    //paste the text
    var WholeString = ControlOnWhichToBePasted.value;
    var txt1 = WholeString.substring(0, CaretPos);
    var txt2 = WholeString.substring(CaretPos, WholeString.length);
    WholeString = txt1 + TextToBePasted + txt2;
    var CaretPos = txt1.length + TextToBePasted.length;
    ControlOnWhichToBePasted.value = WholeString;

    //update The cursor position 
    setCaretPosition(ControlOnWhichToBePasted, CaretPos);
}

function setCaretPosition(ControlOnWhichToBePasted, pos) {

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

</script>

2voto

DreadPirateShawn Points 3801

Je pense que vous pourriez utiliser le JavaScript suivant pour suivre la dernière zone de texte focalisée :

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

function appendTextToLastFocus(text)
{
    holdFocus.value += text;
}
</script>

Utilisation :

<input type="textbox" onfocus="updateFocus(this)" />
<a href="#" onclick="appendTextToLastFocus('textToAppend')" />

Une solution précédente (grâce à gclaghorn) utilise un textarea et calcule également la position du curseur, ce qui peut être mieux adapté à ce que vous voulez. D'un autre côté, celle-ci serait plus légère, si c'est ce que vous recherchez.

0 votes

Bonne idée. J'ai utilisé jquery pour que chaque textbox ayant une certaine classe ait cet événement appliqué à eux plutôt que de devoir mettre "onfocus=..." dans le html de chaque textbox. Mais bonne approche :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X