Einfügen eines Textes, bei dem der Cursor Javascript / jquery verwendet

167

Ich habe eine Seite mit vielen Textfeldern. Wenn jemand auf einen Link klickt, möchte ich, dass ein oder zwei Wörter an der Stelle eingefügt werden, an der sich der Cursor befindet, oder an das Textfeld angehängt werden, das den Fokus hat.

Wenn sich der Cursor / Fokus beispielsweise auf einem Textfeld mit der Aufschrift "Apfel" befindet und er auf einen Link mit der Aufschrift "[E-Mail]" klickt, soll das Textfeld "Apfel [email protected]" lauten.

Wie kann ich das machen? Ist das überhaupt möglich, denn was ist, wenn der Fokus auf einem Radio / Dropdown / Nicht-Textbox-Element liegt? Kann man sich an das letzte Textfeld erinnern?

Klicken Sie auf Upvote
quelle
Ich nehme an, es ist möglich, weil es die Basis der WYSISYG-Editoren ist. Ich weiß nicht, wie es geht.
Ian Elliott
Vielen Dank, dass Sie diese Frage gestellt haben ... jetzt kann ich mit meiner Chrome-Erweiterung "[Version]" am Cursor einfügen!
Haykam
Wenn Sie nach einem einfachen Modul mit Rückgängig-Unterstützung suchen, versuchen Sie , Text-Textbereich einzufügen . Wenn Sie IE8 + -Unterstützung benötigen, probieren Sie das Paket " Text am Cursor einfügen" aus .
fregante

Antworten:

241

Verwenden Sie dies von hier aus :

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>

George Claghorn
quelle
7
Dies hat gut funktioniert, aber es ersetzt nicht das Ersetzen von ausgewähltem Text wie alle Texteditoren. Dies wird möglicherweise nicht für die ursprüngliche Frage des Posters benötigt, aber wenn Sie es brauchen, können Sie einfach 'strPos' durch 'txtArea.selectionEnd' ersetzen. Meine Antwort unten zeigt dies zusammen mit dem Entfernen des Browsererkennungscodes, wenn Sie ältere Versionen von IE nicht unterstützen müssen.
Jeffrey Harmon
Gibt es eine Möglichkeit, alle Elemente mit auszuwählen areaId?
Haykam
1
Sie können das automatische Löschen des ausgewählten Textes erreichen, indem Sie eine solche Funktion einfügen. 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; }
NSTuttle
Wie füge ich Text an der Mausposition ein?
Thamarai T
Du bist der beste!
Ecko Santoso
156

Vielleicht wäre eine kürzere Version leichter zu verstehen?

    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" />

Ich habe dies als Antwort auf Wie füge ich einen Text zu einem Textfeld von der aktuellen Position des Zeigers mit jquery hinzu?

quik_silv
quelle
11
Sie können die Caret-Position auch wiederherstellen, nachdem Sie den Wert geändert haben mit : document.getElementById("txt").selectionStart = caretPos + txtToAdd.length.
Bludwarf
1
hat für mich gearbeitet, danke. Zu Ihrer Information, die Eigenschaft "selectionStart" existiert nicht über den jquery selector $ ("#"). Sie müssen document.getElementById ()
Lego
1
jsfiddle.net/NaHTw/802 ist Ihre Lösung mit einem kleinen Extra, das hinzugefügt wird, um den ausgewählten Bereich durch das zu ersetzen, was eingefügt wurde
Patrick
3
Wenn Sie so weit gehen, um die jQuery zu entfernen, können Sie auch alles entfernen . ; ^)
Ruffin
8
Nur um zu helfen, hier ist die vollständige Lösung mit Wiederherstellung der Caret-Position und Ersetzen des ausgewählten Bereichs durch eingefügten Inhalt: jsfiddle.net/NaHTw/1028
AlfaTeK
41

Die genehmigte Antwort von George Claghorn funktionierte hervorragend, um einfach Text an der Cursorposition einzufügen. Wenn der Benutzer jedoch Text ausgewählt hat und dieser Text ersetzt werden soll (die Standarderfahrung bei den meisten Texten), müssen Sie beim Festlegen der Variablen "Zurück" eine kleine Änderung vornehmen.

Wenn Sie ältere IE-Versionen nicht unterstützen müssen, unterstützen moderne Versionen textarea.selectionStart, sodass Sie die gesamte Browsererkennung und den IE-spezifischen Code entfernen können.

Hier ist eine vereinfachte Version, die mindestens für Chrome und IE11 funktioniert und das Ersetzen von ausgewähltem Text übernimmt.

function insertAtCaret(areaId, text) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var caretPos = txtarea.selectionStart;

    var front = (txtarea.value).substring(0, caretPos);
    var back = (txtarea.value).substring(txtarea.selectionEnd, txtarea.value.length);
    txtarea.value = front + text + back;
    caretPos = caretPos + text.length;
    txtarea.selectionStart = caretPos;
    txtarea.selectionEnd = caretPos;
    txtarea.focus();
    txtarea.scrollTop = scrollPos;
}
Jeffrey Harmon
quelle
Dies ist gut, maxlengthberücksichtigt jedoch nicht die Elemente , sodass der resultierende Wert nach dem Einfügen länger als das Maximum sein kann.
mbomb007
22

Der obige Code hat bei mir im IE nicht funktioniert. Hier ist ein Code, der auf dieser Antwort basiert .

Ich habe das herausgenommen, getElementByIddamit ich das Element auf eine andere Weise referenzieren kann.

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>

BEARBEITEN: Ein laufendes Snippet wurde hinzugefügt. JQuery wird nicht verwendet .

Collin Anderson
quelle
Ist element ein jquery-Objekt oder nicht? element.value und element.focus () können nicht beide funktionieren ...
Scott Stafford
7
element.focus()ist eine legitime JavaScript-Methode auf DOMElements: w3schools.com/jsref/met_html_focus.asp
oliverseal
1
Die beste Idee ist, die IE-Kompatibilität zu löschen.
ar2015
2
Ja, ich habe diese Antwort vor 7 Jahren geschrieben. Zu diesem Zeitpunkt ist IE 11 eine gute, mindestens unterstützte Version, und der obige Code funktioniert dort.
Collin Anderson
6

mit @quick_sliv Antwort:

function insertAtCaret(el, text) {
    var caretPos = el.selectionStart;
    var textAreaTxt = el.value;
    el.value = textAreaTxt.substring(0, caretPos) + text + textAreaTxt.substring(caretPos);
};
math2001
quelle
4

So fügen Sie über JQuery und JavaScript Text in die aktuelle Cursorposition einer TextBox ein

Prozess

  1. Suchen Sie die aktuelle Cursorposition
  2. Holen Sie sich den zu kopierenden Text
  3. Stellen Sie dort den Text ein
  4. Aktualisieren Sie die Cursorposition

Hier habe ich 2 Textboxen und einen Button. Ich muss auf eine bestimmte Position in einem Textfeld klicken und dann auf die Schaltfläche klicken, um den Text aus dem anderen Textfeld an die Position des vorherigen Textfelds einzufügen.

Das Hauptproblem hierbei ist, dass die aktuelle Cursorposition abgerufen wird, an der der Text eingefügt wird.

//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>
Sunil K Behera -MindFire Sol-
quelle
3

Das Hinzufügen von Text zur aktuellen Cursorposition umfasst zwei Schritte:

  1. Hinzufügen des Textes an der aktuellen Cursorposition
  2. Aktualisieren der aktuellen Cursorposition

Demo: https://codepen.io/anon/pen/qZXmgN

Getestet in Chrome 48, Firefox 45, IE 11 und Edge 25

JS:

function addTextAtCaret(textAreaId, text) {
    var textArea = document.getElementById(textAreaId);
    var cursorPosition = textArea.selectionStart;
    addTextAtCursorPosition(textArea, cursorPosition, text);
    updateCursorPosition(cursorPosition, text, textArea);
}
function addTextAtCursorPosition(textArea, cursorPosition, text) {
    var front = (textArea.value).substring(0, cursorPosition);
    var back = (textArea.value).substring(cursorPosition, textArea.value.length);
    textArea.value = front + text + back;
}
function updateCursorPosition(cursorPosition, text, textArea) {
    cursorPosition = cursorPosition + text.length;
    textArea.selectionStart = cursorPosition;
    textArea.selectionEnd = cursorPosition;
    textArea.focus();    
}

HTML:

<div>
    <button type="button" onclick="addTextAtCaret('textArea','Apple')">Insert Apple!</button>
    <button type="button" onclick="addTextAtCaret('textArea','Mango')">Insert Mango!</button>
    <button type="button" onclick="addTextAtCaret('textArea','Orange')">Insert Orange!</button>
</div>
<textarea id="textArea" rows="20" cols="50"></textarea>
Razan Paul
quelle
2

Ich denke, Sie könnten das folgende JavaScript verwenden, um das zuletzt fokussierte Textfeld zu verfolgen:

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

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

Verwendung:

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

Eine frühere Lösung (Requisiten für Gclaghorn) verwendet Textbereich und berechnet auch die Position des Cursors, sodass es möglicherweise besser für das ist, was Sie möchten. Auf der anderen Seite wäre dieser leichter, wenn Sie danach suchen.

DreadPirateShawn
quelle
Gute Idee. Ich habe jquery verwendet, damit auf jedes Textfeld mit einer bestimmten Klasse dieses Ereignis angewendet wurde, anstatt "onfocus = ..." in das HTML jedes Textfelds einfügen zu müssen. Aber guter Ansatz :)
Klicken Sie auf Upvote
1

Die akzeptierte Antwort funktionierte in Internet Explorer 9 nicht für mich. Ich habe sie überprüft und die Browsererkennung funktionierte nicht richtig. Als ich im Internet Explorer war , wurde ff (Firefox) erkannt .

Ich habe gerade diese Änderung vorgenommen:

if ($.browser.msie) 

Anstatt:

if (br == "ie") { 

Der resultierende Code ist folgender:

function insertAtCaret(areaId,text) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var strPos = 0;
    var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ? 
        "ff" : (document.selection ? "ie" : false ) );

    if ($.browser.msie) { 
        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 range = document.selection.createRange();
        range.moveStart ('character', -txtarea.value.length);
        range.moveStart ('character', strPos);
        range.moveEnd ('character', 0);
        range.select();
    }
    else if (br == "ff") {
        txtarea.selectionStart = strPos;
        txtarea.selectionEnd = strPos;
        txtarea.focus();
    }
    txtarea.scrollTop = scrollPos;
}
Alvaro
quelle
1

Dieses jQuery-Plugin bietet Ihnen eine vorgefertigte Möglichkeit zur Auswahl / Caret-Manipulation.

Chris S.
quelle
0

Sie können nur das erforderliche Textfeld fokussieren und den Text dort einfügen. Es gibt keine Möglichkeit herauszufinden, wo der Fokus auf AFAIK liegt (möglicherweise über alle DOM-Knoten hinweg?).

Überprüfen Sie diesen Stapelüberlauf - er hat eine Lösung für Sie: Wie finde ich heraus, welches DOM-Element den Fokus hat?

dusoft
quelle
0

Inhalt bearbeitbar, HTML oder eine andere DOM-Elementauswahl

Wenn Sie versuchen, bei Caret auf einem einzufügen <div contenteditable="true">, wird dies viel schwieriger, insbesondere wenn sich Kinder im bearbeitbaren Container befinden.

Ich hatte wirklich großes Glück mit der Rangy- Bibliothek:

Es hat eine Menge großartiger Funktionen wie:

  • Position oder Auswahl speichern
  • Stellen Sie später die Position oder Auswahl wieder her
  • Holen Sie sich Auswahl HTML oder Plaintext
  • Unter vielen anderen

Die Online-Demo funktionierte zuletzt nicht, aber das Repo hat funktionierende Demos. Laden Sie zunächst das Repo von Git oder NPM herunter und öffnen Sie ./rangy/demos/index.html

Es macht das Arbeiten mit Caret Pos und Textauswahl zum Kinderspiel!

factorypolaris
quelle
0

Die Antwort auf diese Frage wurde vor so langer Zeit veröffentlicht und ich bin über eine Google-Suche darauf gestoßen. HTML5 bietet die HTMLInputElement-API , die die setRangeText () -Methode enthält, die einen Textbereich in einem <input>oder <textarea>-Element durch eine neue Zeichenfolge ersetzt:

element.setRangeText('abc');

Die oben ersetzen würde die Auswahl getroffen innen elementmit abc. Sie können auch angeben, welcher Teil des Eingabewerts ersetzt werden soll:

element.setRangeText('abc', 3, 5);

Das Obige würde das 4. bis 6. Zeichen des Eingabewerts durch ersetzen abc. Sie können auch festlegen, wie die Auswahl festgelegt werden soll, nachdem der Text ersetzt wurde, indem Sie eine der folgenden Zeichenfolgen als vierten Parameter angeben:

  • 'preserve'versucht, die Auswahl beizubehalten. Dies ist die Standardeinstellung.
  • 'select' wählt den neu eingefügten Text aus.
  • 'start' Verschiebt die Auswahl kurz vor den eingefügten Text.
  • 'end' Verschiebt die Auswahl direkt nach dem eingefügten Text.

Browser-Kompatibilität

Die MDN-Seite für setRangeText enthält keine Browserkompatibilitätsdaten, aber ich denke, sie entspricht der HTMLInputElement.setSelectionRange () , bei der es sich im Grunde um alle modernen Browser handelt, IE 9 und höher, Edge 12 und höher.

A. Genedy
quelle