Hoe voeg ik tekst in het tekstgebied in op de huidige cursorpositie?

Ik zou graag een eenvoudige functie willen maken die tekst toevoegt aan een tekstgebied op de cursorpositie van de gebruiker. Het moet een schone functie zijn. Alleen de basis. De rest kan ik wel bedenken.


Antwoord 1, autoriteit 100%

Gebruik selectionStart/selectionEndeigenschappen van het invoerelement(werkt ook voor <textarea>)

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

Antwoord 2, autoriteit 66%

Dit fragment kan je hiermee helpen in een paar regels van jQuery 1.9+: http://jsfiddle.net /4MBUG/2/

$('input[type=button]').on('click', function() {
    var cursorPos = $('#text').prop('selectionStart');
    var v = $('#text').val();
    var textBefore = v.substring(0,  cursorPos);
    var textAfter  = v.substring(cursorPos, v.length);
    $('#text').val(textBefore + $(this).val() + textAfter);
});

Antwoord 3, autoriteit 32%

Voor het juiste Javascript

HTMLTextAreaElement.prototype.insertAtCaret = function (text) {
  text = text || '';
  if (document.selection) {
    // IE
    this.focus();
    var sel = document.selection.createRange();
    sel.text = text;
  } else if (this.selectionStart || this.selectionStart === 0) {
    // Others
    var startPos = this.selectionStart;
    var endPos = this.selectionEnd;
    this.value = this.value.substring(0, startPos) +
      text +
      this.value.substring(endPos, this.value.length);
    this.selectionStart = startPos + text.length;
    this.selectionEnd = startPos + text.length;
  } else {
    this.value += text;
  }
};

Antwoord 4, autoriteit 30%

Nieuw antwoord:

https://developer.mozilla.org/en- VS/docs/Web/API/HTMLInputElement/setRangeText

Ik ben echter niet zeker van de browserondersteuning hiervoor.

Getest in Chrome 81.

function typeInTextarea(newText, el = document.activeElement) {
  const [start, end] = [el.selectionStart, el.selectionEnd];
  el.setRangeText(newText, start, end, 'select');
}
document.getElementById("input").onkeydown = e => {
  if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>
<div>It'll replace a selection with the given text.</div>

Snippet uitvouwen


Antwoord 5, autoriteit 15%

Een eenvoudige oplossing die werkt op Firefox, Chrome, Opera, Safari en de rand, maar waarschijnlijk zal niet werken op oude IE browsers.

var target = document.getElementById("mytextarea_id")
if (target.setRangeText) {
    //if setRangeText function is supported by current browser
    target.setRangeText(data)
} else {
    target.focus()
    document.execCommand('insertText', false /*no UI*/, data);
}

setRangeTextfunctie kunt u de huidige selectie vervangen door de meegeleverde tekst of indien er geen selectie plaats de tekst cursor. Het wordt alleen ondersteund door firefox voor zover ik weet.

Voor andere browsers is er “insertText” commando dat alleen van invloed op de html element op dit moment gericht en heeft hetzelfde gedrag als setRangeText

dele Hierdoor geïnspireerd artikel


Antwoord 6, Autoriteit 8%

I like simple javascript , en ik heb meestal jQuery in de buurt. Hier is wat ik bedacht, gebaseerd off mparkuk is

function typeInTextarea(el, newText) {
    var start = el.prop("selectionStart")
    var end = el.prop("selectionEnd")
    var text = el.val()
    var before = text.substring(0, start)
    var after  = text.substring(end, text.length)
    el.val(before + newText + after)
    el[0].selectionStart = el[0].selectionEnd = start + newText.length
    el.focus()
}
$("button").on("click", function() {
    typeInTextarea($("textarea"), "some text")
    return false
})

Hier is een demo: http://codepen.io/erikpukinskis/pen/EjaaMY ? redacteuren = 101


Antwoord 7, Autoriteit 7%

Rab antwoord werkt geweldig, maar niet voor Microsoft Edge, zodat voegde ik een kleine aanpassing voor Edge ook:

https://jsfiddle.net/et9borp4/

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 
      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 
      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

Antwoord 8, autoriteit 4%

function insertAtCaret(text) {
  const textarea = document.querySelector('textarea')
  textarea.setRangeText(
    text,
    textarea.selectionStart,
    textarea.selectionEnd,
    'end'
  )
}
setInterval(() => insertAtCaret('Hello'), 3000)
<textarea cols="60">Stack Overflow Stack Exchange Starbucks Coffee</textarea>

Snippet uitvouwen


Antwoord 9, autoriteit 4%

Als de gebruiker de invoer niet aanraakt nadat er tekst is ingevoegd, wordt de ‘invoer’-gebeurtenis nooit geactiveerd en geeft het waardeattribuut de wijziging niet weer. Daarom is het belangrijk om de invoergebeurtenis te activeren na het programmatisch invoegen van tekst. Focussen op het veld is niet genoeg.

Het volgende is een kopie van Snorvarg’s antwoordmet een invoertrigger aan het einde:

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 
      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 
      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
    triggerEvent(myField,'input');
}
function triggerEvent(el, type){
  if ('createEvent' in document) {
    // modern browsers, IE9+
    var e = document.createEvent('HTMLEvents');
    e.initEvent(type, false, true);
    el.dispatchEvent(e);
  } else {
    // IE 8
    var e = document.createEventObject();
    e.eventType = type;
    el.fireEvent('on'+e.eventType, e);
  }
}

Met dank aan plainjs.comvoor de triggerEvent-functie

Meer over het oninput-evenement op w3schools.com

Ik ontdekte dit tijdens het maken van een emoji-kiezer voor een chat. Als de gebruiker slechts een paar emoji’s selecteert en op de knop “verzenden” drukt, wordt het invoerveld nooit door de gebruiker aangeraakt. Bij het controleren van het waardeattribuut was het altijd leeg, hoewel de ingevoegde emoji-unicodes zichtbaar waren in het invoerveld. Het blijkt dat als de gebruiker het veld niet aanraakt, de ‘input’-gebeurtenis nooit is geactiveerd en de oplossing was om het op deze manier te activeren. Het kostte nogal wat tijd om dit uit te zoeken… ik hoop dat het iemand wat tijd zal besparen.


Antwoord 10

De onderstaande code is een TypeScript-aanpassing van het pakket https://github.com /grassator/insert-text-at-cursordoor Dmitriy Kubyshkin.


/**
 * Inserts the given text at the cursor. If the element contains a selection, the selection
 * will be replaced by the text.
 */
export function insertText(input: HTMLTextAreaElement | HTMLInputElement, text: string) {
  // Most of the used APIs only work with the field selected
  input.focus();
  // IE 8-10
  if ((document as any).selection) {
    const ieRange = (document as any).selection.createRange();
    ieRange.text = text;
    // Move cursor after the inserted text
    ieRange.collapse(false /* to the end */);
    ieRange.select();
    return;
  }
  // Webkit + Edge
  const isSuccess = document.execCommand("insertText", false, text);
  if (!isSuccess) {
    const start = input.selectionStart;
    const end = input.selectionEnd;
    // Firefox (non-standard method)
    if (typeof (input as any).setRangeText === "function") {
      (input as any).setRangeText(text);
    } else {
      if (canManipulateViaTextNodes(input)) {
        const textNode = document.createTextNode(text);
        let node = input.firstChild;
        // If textarea is empty, just insert the text
        if (!node) {
          input.appendChild(textNode);
        } else {
          // Otherwise we need to find a nodes for start and end
          let offset = 0;
          let startNode = null;
          let endNode = null;
          // To make a change we just need a Range, not a Selection
          const range = document.createRange();
          while (node && (startNode === null || endNode === null)) {
            const nodeLength = node.nodeValue.length;
            // if start of the selection falls into current node
            if (start >= offset && start <= offset + nodeLength) {
              range.setStart((startNode = node), start - offset);
            }
            // if end of the selection falls into current node
            if (end >= offset && end <= offset + nodeLength) {
              range.setEnd((endNode = node), end - offset);
            }
            offset += nodeLength;
            node = node.nextSibling;
          }
          // If there is some text selected, remove it as we should replace it
          if (start !== end) {
            range.deleteContents();
          }
          // Finally insert a new node. The browser will automatically
          // split start and end nodes into two if necessary
          range.insertNode(textNode);
        }
      } else {
        // For the text input the only way is to replace the whole value :(
        const value = input.value;
        input.value = value.slice(0, start) + text + value.slice(end);
      }
    }
    // Correct the cursor position to be at the end of the insertion
    input.setSelectionRange(start + text.length, start + text.length);
    // Notify any possible listeners of the change
    const e = document.createEvent("UIEvent");
    e.initEvent("input", true, false);
    input.dispatchEvent(e);
  }
}
function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement) {
  if (input.nodeName !== "TEXTAREA") {
    return false;
  }
  let browserSupportsTextareaTextNodes;
  if (typeof browserSupportsTextareaTextNodes === "undefined") {
    const textarea = document.createElement("textarea");
    textarea.value = "1";
    browserSupportsTextareaTextNodes = !!textarea.firstChild;
  }
  return browserSupportsTextareaTextNodes;
}

Antwoord 11

Medewerkingsfunctie plaatsen voor eigen referentie. Dit voorbeeld voegt een geselecteerd item in van <select>Object en plaatst de gardate tussen de tags:

//Inserts a choicebox selected element into target by id
function insertTag(choicebox,id) {
    var ta=document.getElementById(id)
    ta.focus()
    var ss=ta.selectionStart
    var se=ta.selectionEnd
    ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length)
    ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2)
}

Antwoord 12

/**
 * Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz"
 */
String.prototype.insertInside = function(start, delCount, newSubStr) {
    return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
};
$('textarea').bind("keydown keypress", function (event) {
    var val = $(this).val();
    var indexOf = $(this).prop('selectionStart');
    if(event.which === 13) {
        val = val.insertInside(indexOf, 0,  "<br>\n");
        $(this).val(val);
        $(this).focus();
    }
});

Antwoord 13

gewijzigd in getElementById(myField):

function insertAtCursor(myField, myValue) {
    // IE support
    if (document.selection) {
        document.getElementById(myField).focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // MOZILLA and others
    else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
        var startPos = document.getElementById(myField).selectionStart;
        var endPos = document.getElementById(myField).selectionEnd;
        document.getElementById(myField).value =
                document.getElementById(myField).value.substring(0, startPos)
                + myValue
                + document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
    } else {
        document.getElementById(myField).value += myValue;
    }
}

Other episodes