Menyisipkan teks tempat kursor menggunakan Javascript / jquery

167

Saya memiliki halaman dengan banyak kotak teks. Ketika seseorang mengklik sebuah tautan, saya ingin satu atau dua kata dimasukkan di mana kursor berada, atau ditambahkan ke kotak teks yang memiliki fokus.

Misalnya, jika kursor / fokus berada pada kotak teks bertuliskan 'apel' dan dia mengklik tautan yang mengatakan '[email]', maka saya ingin kotak teks itu mengatakan, 'apple [email protected]'.

Bagaimana saya bisa melakukan ini? Apakah ini bahkan mungkin, karena bagaimana jika fokusnya adalah pada elemen radio / dropdown / non textbox? Bisakah yang terakhir berfokus pada kotak teks diingat?

Klik Upvote
sumber
Saya berasumsi itu mungkin karena itu adalah dasar dari editor WYSISYG, bagaimana melakukannya, saya tidak tahu.
Ian Elliott
Terima kasih telah mengajukan pertanyaan ini ... sekarang saya dapat memasukkan "[versi]" di kursor dengan ekstensi Chrome saya!
haykam
Jika Anda mencari modul sederhana dengan dukungan undo, coba masukkan-teks-textarea . Jika Anda memerlukan dukungan IE8 +, cobalah paket sisipkan teks pada kursor .
fregante

Jawaban:

241

Gunakan ini, dari sini :

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
sumber
7
Ini bekerja dengan baik, tetapi tidak menangani penggantian teks yang dipilih seperti yang dilakukan semua editor teks. Ini mungkin tidak diperlukan untuk pertanyaan asli poster, tetapi jika Anda membutuhkannya, Anda cukup mengganti 'strPos' dengan 'txtArea.selectionEnd'. Jawaban saya di bawah menunjukkan ini, bersama dengan menghapus kode deteksi browser, jika Anda tidak perlu mendukung versi IE yang lebih lama.
Jeffrey Harmon
Apakah ada cara untuk memilih semua elemen areaId?
haykam
1
Anda dapat mencapai penghapusan otomatis teks yang dipilih dengan menyisipkan fungsi seperti ini. 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
Bagaimana cara memasukkan teks pada posisi mouse?
Thamarai T
Kamu yang terbaik!
Ecko Santoso
156

Mungkin versi yang lebih pendek, akan lebih mudah dimengerti?

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

Saya menulis ini sebagai tanggapan terhadap Bagaimana cara menambahkan teks ke kotak teks dari posisi pointer saat ini dengan jquery?

quik_silv
sumber
11
Anda juga dapat mengembalikan posisi sisipan setelah mengubah nilai dengan: document.getElementById("txt").selectionStart = caretPos + txtToAdd.length.
Bludwarf
1
bekerja untuk saya, terima kasih. FYI properti "selectionStart" tidak ada melalui pemilih jquery $ ("#"). Anda harus membuka document.getElementById ()
Lego
1
jsfiddle.net/NaHTw/802 adalah solusi Anda dengan sedikit tambahan ditambahkan untuk mengganti area yang dipilih dengan apa yang ditempelkan
patrick
3
Nah, jika Anda ingin menghapus jQuery sejauh itu, Anda bisa menghapus semuanya . ; ^)
ruffin
8
Untuk membantu, inilah solusi lengkap dengan mengembalikan posisi caret plus mengganti area yang dipilih dengan konten yang disisipkan: jsfiddle.net/NaHTw/1028
AlfaTeK
41

Jawaban yang disetujui dari George Claghorn bekerja sangat baik untuk hanya memasukkan teks pada posisi kursor. Jika pengguna telah memilih teks, dan Anda ingin teks itu diganti (pengalaman default dengan sebagian besar teks), Anda harus membuat perubahan kecil ketika mengatur variabel 'kembali'.

Juga, jika Anda tidak perlu mendukung versi IE yang lebih lama, versi modern mendukung textarea.selectionStart, sehingga Anda dapat menghapus semua deteksi browser, dan kode khusus IE.

Berikut adalah versi yang disederhanakan yang paling tidak berfungsi untuk Chrome dan IE11, dan menangani penggantian teks yang dipilih.

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
sumber
Ini bagus, tetapi tidak memperhitungkan unsur maxlength, jadi nilai yang dihasilkan setelah penyisipan bisa lebih lama dari maksimum.
mbomb007
22

Kode di atas tidak berfungsi untuk saya di IE. Inilah beberapa kode berdasarkan jawaban ini .

Saya mengambil getElementByIdsehingga saya bisa referensi elemen dengan cara yang berbeda.

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>

Sunting: Menambahkan cuplikan yang sedang berjalan, jQuery tidak sedang digunakan .

Collin Anderson
sumber
Apakah elemen objek jquery atau tidak? element.value dan element.focus () tidak bisa berfungsi ...
Scott Stafford
7
element.focus()adalah metode JavaScript yang sah di DOMElements: w3schools.com/jsref/met_html_focus.asp
oliverseal
1
Ide terbaik adalah untuk menjatuhkan kompatibilitas IE.
ar2015
2
Ya, saya menulis jawaban ini 7 tahun yang lalu. Pada titik ini IE 11 adalah versi minimum yang didukung baik, dan kode di atas berfungsi di sana.
Collin Anderson
6

menggunakan jawaban @quick_sliv:

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

Cara memasukkan beberapa Teks ke posisi kursor saat ini dari TextBox melalui JQuery dan JavaScript

Proses

  1. Temukan Posisi Kursor Saat Ini
  2. Dapatkan Teks untuk Disalin
  3. Atur Teks Di sana
  4. Perbarui posisi Kursor

Di sini saya memiliki 2 Kotak Teks dan Tombol. Saya harus Klik pada posisi tertentu pada kotak teks dan kemudian klik tombol untuk menempelkan teks dari kotak teks lain ke posisi kotak teks sebelumnya.

Masalah utama di sini adalah mendapatkan posisi kursor saat ini di mana kami akan menempelkan teks.

//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-
sumber
3

Menambahkan teks ke posisi kursor saat ini melibatkan dua langkah:

  1. Menambahkan teks pada posisi kursor saat ini
  2. Memperbarui posisi kursor saat ini

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

Diuji di Chrome 48, Firefox 45, IE 11 dan 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
sumber
2

Saya pikir Anda bisa menggunakan JavaScript berikut untuk melacak kotak teks yang terakhir difokuskan:

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

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

Pemakaian:

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

Solusi sebelumnya (props to gclaghorn) menggunakan textarea dan menghitung posisi kursor juga, jadi mungkin lebih baik untuk apa yang Anda inginkan. Di sisi lain, yang ini akan lebih ringan, jika itu yang Anda cari.

DreadPirateShawn
sumber
Ide bagus. Saya menggunakan jquery sehingga setiap kotak teks yang memiliki kelas tertentu memiliki acara ini diterapkan pada mereka daripada harus meletakkan "onfocus = ..." di html setiap kotak teks. Tapi pendekatan yang bagus :)
Klik Upvote
1

Jawaban yang diterima tidak berfungsi untuk saya di Internet Explorer 9. Saya memeriksanya dan deteksi browser tidak berfungsi dengan baik, ia mendeteksi ff (firefox) ketika saya berada di Internet Explorer.

Saya baru saja melakukan perubahan ini:

if ($.browser.msie) 

Dari pada:

if (br == "ie") { 

Kode yang dihasilkan adalah yang ini:

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
sumber
1

Plugin jQuery ini memberi Anda cara manipulasi seleksi / caret yang sudah dibuat sebelumnya.

Chris S
sumber
0

Konten yang Dapat Diedit, HTML, atau Pilihan elemen DOM lainnya

Jika Anda mencoba memasukkan di caret pada <div contenteditable="true">, ini menjadi jauh lebih sulit, terutama jika ada anak-anak di dalam wadah yang dapat diedit.

Saya sangat beruntung menggunakan perpustakaan Rangy :

Ini memiliki banyak fitur hebat seperti:

  • Simpan Posisi atau Pilihan
  • Kemudian, Kembalikan Posisi atau Pilihan
  • Dapatkan HTML atau Plaintext pilihan
  • Di antara banyak lainnya

Demo online tidak berfungsi terakhir saya periksa, namun repo memiliki demo yang berfungsi. Untuk memulai, unduh Repo dari Git atau NPM secara sederhana, lalu buka ./rangy/demos/index.html

Itu membuat bekerja dengan pos tanda dan pemilihan teks menjadi mudah!

faktorypolaris
sumber
0

Jawaban pertanyaan ini telah diposting sejak lama dan saya menemukannya melalui pencarian Google. HTML5 menyediakan API HTMLInputElement yang mencakup metode setRangeText () , yang menggantikan berbagai teks dalam elemen <input>atau <textarea>dengan string baru:

element.setRangeText('abc');

Di atas akan menggantikan seleksi yang dilakukan di dalam elementdengan abc. Anda juga dapat menentukan bagian mana dari nilai input yang akan diganti:

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

Di atas akan menggantikan karakter ke-4 hingga ke-6 dari nilai input abc. Anda juga dapat menentukan bagaimana pemilihan harus ditetapkan setelah teks diganti dengan memberikan salah satu dari string berikut sebagai parameter ke-4:

  • 'preserve'upaya untuk melestarikan seleksi. Ini standarnya.
  • 'select' memilih teks yang baru dimasukkan.
  • 'start' memindahkan pilihan tepat sebelum teks yang dimasukkan.
  • 'end' memindahkan pilihan hanya setelah teks yang dimasukkan.

Kompatibilitas browser

Halaman MDN untuk setRangeText tidak menyediakan data kompatibilitas browser, tapi saya kira itu akan sama dengan HTMLInputElement.setSelectionRange () , yang pada dasarnya adalah semua browser modern, IE 9 dan di atasnya, Edge 12 ke atas.

A. Genedy
sumber