Chèn văn bản nơi con trỏ đang sử dụng Javascript / jquery


167

Tôi có một trang với rất nhiều hộp văn bản. Khi ai đó nhấp vào liên kết, tôi muốn chèn một hoặc hai từ vào vị trí con trỏ hoặc gắn vào hộp văn bản có tiêu điểm.

Ví dụ: nếu con trỏ / tiêu điểm nằm trên hộp văn bản có nội dung 'apple' và anh ấy nhấp vào liên kết có nội dung '[email]', thì tôi muốn hộp văn bản nói, 'apple bob@example.com'.

Tôi có thể làm cái này như thế nào? Điều này thậm chí có thể, vì điều gì sẽ xảy ra nếu tiêu điểm nằm ở phần tử radio / dropdown / non textbox? Có thể ghi nhớ cuối cùng vào hộp văn bản?


Tôi cho rằng điều đó là có thể bởi vì đó là nền tảng của các biên tập viên WYSISYG, làm thế nào để làm điều đó, tôi không biết.
Ian Elliott


Cảm ơn bạn đã hỏi câu hỏi này ... bây giờ tôi có thể chèn "[phiên bản]" vào con trỏ bằng tiện ích mở rộng Chrome của mình!
haykam

Nếu bạn đang tìm kiếm một mô-đun đơn giản với hỗ trợ hoàn tác, hãy thử chèn văn bản-văn bản . Nếu bạn cần hỗ trợ IE8 +, hãy thử gói chèn văn bản tại con trỏ .
Fregante

Câu trả lời:


241

Sử dụng cái này, từ đây :

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
Điều này hoạt động rất tốt, nhưng nó không xử lý thay thế văn bản đã chọn như tất cả các trình soạn thảo văn bản làm. Điều này có thể không cần thiết cho câu hỏi ban đầu của người đăng, nhưng nếu bạn cần nó, bạn chỉ cần thay thế 'strPos' bằng 'txtArea.selectionEnd'. Câu trả lời của tôi dưới đây cho thấy điều này, cùng với việc xóa mã phát hiện trình duyệt, nếu bạn không cần hỗ trợ các phiên bản IE cũ hơn.
Jeffrey Harmon

Có cách nào để chọn tất cả các yếu tố với areaId?
haykam

1
Bạn có thể tự động xóa văn bản đã chọn bằng cách chèn một chức năng như thế này. 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; }
NST mực

Làm thế nào để chèn văn bản tại vị trí chuột?
Thamarai T

Bạn là nhất!
Ecko Santoso

156

Có lẽ một phiên bản ngắn hơn, sẽ dễ hiểu hơn?

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

Tôi đã viết điều này để đáp lại Làm thế nào để thêm một văn bản vào một hộp văn bản từ vị trí hiện tại của con trỏ với jquery?


11
Bạn cũng có thể khôi phục vị trí dấu mũ sau khi thay đổi giá trị với : document.getElementById("txt").selectionStart = caretPos + txtToAdd.length.
Bludwarf

1
làm việc cho tôi, cảm ơn. FYI thuộc tính "selectStart" không tồn tại thông qua bộ chọn jquery $ ("#"). Bạn cần phải đi qua document.getEuityById ()
Lego

1
jsfiddle.net/NaHTw/802 là giải pháp của bạn với một chút bổ sung để thay thế khu vực đã chọn bằng những gì đã dán
patrick

3
Chà, nếu bạn sẽ đi xa đến mức gỡ bỏ jQuery, bạn cũng có thể xóa tất cả . ; ^)
ruffin

8
Chỉ để giúp đỡ, đây là giải pháp hoàn chỉnh với khôi phục vị trí dấu mũ cộng với thay thế vùng đã chọn bằng nội dung đã dán: jsfiddle.net/NaHTw/1028
AlfaTeK

41

Câu trả lời được phê duyệt từ George Claghorn hoạt động rất tốt vì chỉ cần chèn văn bản vào vị trí con trỏ. Nếu người dùng đã chọn văn bản mặc dù và bạn muốn văn bản đó được thay thế (trải nghiệm mặc định với hầu hết văn bản), bạn cần thực hiện một thay đổi nhỏ khi đặt biến 'trở lại'.

Ngoài ra, nếu bạn không cần hỗ trợ các phiên bản IE cũ hơn, các phiên bản hiện đại hỗ trợ textarea.selectionStart, để bạn có thể loại bỏ tất cả các phát hiện trình duyệt và mã dành riêng cho IE.

Đây là phiên bản đơn giản hóa ít nhất hoạt động cho Chrome và IE11 và xử lý thay thế văn bản đã chọn.

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;
}

Điều này là tốt, nhưng nó không tính đến yếu tố maxlength, vì vậy giá trị kết quả sau khi chèn có thể dài hơn mức tối đa.
mbomb007

22

Đoạn mã trên không hoạt động với tôi trong IE. Đây là một số mã dựa trên câu trả lời này .

Tôi lấy ra getElementByIdđể tôi có thể tham chiếu phần tử theo một cách khác.

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: Đã thêm đoạn mã đang chạy, jQuery không được sử dụng .


Là yếu tố một đối tượng jquery hay không? Element.value và Element.f Focus () không thể hoạt động cả ...
Scott Stafford

7
element.focus()là một phương thức JavaScript hợp pháp trên DOMElements: w3schools.com/jsref/met_html_f
Focus.asp

1
Ý tưởng tốt nhất là bỏ khả năng tương thích IE.
ar2015

2
Vâng, tôi đã viết câu trả lời này 7 năm trước. Tại thời điểm này, IE 11 là phiên bản được hỗ trợ tối thiểu tốt và mã ở trên hoạt động ở đó.
Collin Anderson

6

sử dụng câu trả lời @quick_sliv:

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

4

Cách chèn một số Văn bản vào vị trí con trỏ hiện tại của TextBox thông qua JQuery và JavaScript

Quá trình

  1. Tìm vị trí con trỏ hiện tại
  2. Nhận văn bản để được sao chép
  3. Đặt văn bản ở đó
  4. Cập nhật vị trí con trỏ

Ở đây tôi có 2 TextBoxes và một nút. Tôi phải Nhấp vào một vị trí nhất định trên hộp văn bản và sau đó nhấp vào nút để dán văn bản từ hộp văn bản khác vào vị trí của hộp văn bản trước đó.

Vấn đề chính ở đây là có được vị trí con trỏ hiện tại nơi chúng ta sẽ dán văn bản.

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

3

Thêm văn bản vào vị trí con trỏ hiện tại bao gồm hai bước:

  1. Thêm văn bản tại vị trí con trỏ hiện tại
  2. Cập nhật vị trí con trỏ hiện tại

Bản giới thiệu: https://codepen.io/anon/pen/qZXmgN

Đã thử nghiệm trong Chrome 48, Firefox 45, IE 11 và 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>

2

Tôi nghĩ rằng bạn có thể sử dụng JavaScript sau để theo dõi hộp văn bản tập trung cuối cùng:

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

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

Sử dụng:

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

Một giải pháp trước đây (đạo cụ cho gclaghorn) sử dụng textarea và tính toán vị trí của con trỏ, vì vậy nó có thể tốt hơn cho những gì bạn muốn. Mặt khác, cái này sẽ nhẹ hơn, nếu đó là thứ bạn đang tìm kiếm.


Ý tưởng tốt. Tôi đã sử dụng jquery để mỗi hộp văn bản có một lớp nhất định áp dụng sự kiện này cho chúng thay vì phải đặt "onf Focus = ..." trong html của mỗi hộp văn bản. Nhưng cách tiếp cận tốt :)
Nhấp vào Upvote

1

Câu trả lời được chấp nhận không hoạt động với tôi trên Internet Explorer 9. Tôi đã kiểm tra và phát hiện trình duyệt không hoạt động chính xác, nó phát hiện ra ff (firefox) khi tôi ở Internet Explorer.

Tôi vừa mới thực hiện thay đổi này:

if ($.browser.msie) 

Thay vì:

if (br == "ie") { 

Mã kết quả là cái này:

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;
}



0

Nội dung có thể chỉnh sửa, HTML hoặc bất kỳ lựa chọn phần tử DOM nào khác

Nếu bạn đang cố gắng chèn vào dấu mũ trên một <div contenteditable="true"> , điều này trở nên khó khăn hơn nhiều, đặc biệt là nếu có trẻ em trong thùng chứa có thể chỉnh sửa.

Tôi đã rất may mắn khi sử dụng thư viện Rangy :

Nó có rất nhiều tính năng tuyệt vời như:

  • Lưu vị trí hoặc lựa chọn
  • Sau đó, Khôi phục vị trí hoặc lựa chọn
  • Nhận lựa chọn HTML hoặc Bản rõ
  • Trong số nhiều người khác

Bản demo trực tuyến không hoạt động lần cuối tôi đã kiểm tra, tuy nhiên repo có bản demo hoạt động. Để bắt đầu, chỉ cần tải xuống Repo từ Git hoặc NPM, sau đó mở ./rangy/demos/index.html

Nó làm cho làm việc với tư thế caret và lựa chọn văn bản một cách dễ dàng!


0

Câu trả lời của câu hỏi này đã được đăng cách đây rất lâu và tôi tình cờ phát hiện ra nó thông qua một tìm kiếm Google. HTML5 cung cấp API HTMLInputE bổ sung bao gồm phương thức setRangeText () , thay thế một phạm vi văn bản trong một <input>hoặc <textarea>phần tử bằng một chuỗi mới:

element.setRangeText('abc');

Ở trên sẽ thay thế lựa chọn được thực hiện bên trong elementvới abc. Bạn cũng có thể chỉ định phần nào của giá trị đầu vào cần thay thế:

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

Ở trên sẽ thay thế các ký tự thứ 4 đến thứ 6 của giá trị đầu vào bằng abc. Bạn cũng có thể chỉ định cách lựa chọn nên được đặt sau khi văn bản đã được thay thế bằng cách cung cấp một trong các chuỗi sau làm tham số thứ 4:

  • 'preserve'cố gắng để bảo tồn các lựa chọn. Đây là mặc định.
  • 'select' chọn văn bản mới được chèn.
  • 'start' di chuyển lựa chọn đến ngay trước văn bản được chèn.
  • 'end' di chuyển lựa chọn đến ngay sau văn bản được chèn.

Tính tương thích của trình duyệt web

Trang MDN cho setRangeText không cung cấp dữ liệu tương thích trình duyệt, nhưng tôi đoán nó sẽ giống như HTMLInputEuity.setSelectionRange () , về cơ bản là tất cả các trình duyệt hiện đại, IE 9 trở lên, Edge 12 trở lên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.