Вставка текста, где курсор использует Javascript / JQuery

У меня есть страница с большим количеством текстовых полей. Когда кто-то нажимает на ссылку, я хочу, чтобы слово или два были вставлены туда, где находится курсор, или добавлены к текстовому полю с фокусом.

Например, если курсор / фокус находится на текстовом поле с надписью «яблоко»; и он нажимает на ссылку «[электронная почта]», затем я хочу, чтобы в текстовом поле было написано: «apple [email protected]&apos ;.

Как я могу это сделать? Возможно ли это вообще, так как что, если фокус находится на элементе radio / dropdown / non textbox? Можно ли запомнить последнее сосредоточенное на текстовом поле?

 Ian Elliott30 июн. 2009 г., 16:50
Я предполагаю, что это возможно, потому что это основа редакторов WYSISYG, как это сделать, я не знаю.
 haykam28 июл. 2016 г., 21:35
Спасибо за вопрос ... теперь я могу вставить "[версию]" в курсор с моим расширением Chrome!
 dusoft30 июн. 2009 г., 16:50
он требует чего-л. другой
 John14 июн. 2012 г., 15:32

Ответы на вопрос(12)

что вы можете использовать следующий JavaScript для отслеживания последнего текстового поля:

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

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

Использование

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

Предыдущее решение (props to gclaghorn) использует textarea и рассчитывает положение курсора, так что оно может быть лучше для того, что вы хотите. С другой стороны, этот будет более легким, если это то, что вы ищете.

 Click Upvote30 июн. 2009 г., 17:04
Отличная идея. Я использовал jquery, чтобы к каждому текстовому полю, в котором был определенный класс, применялось это событие, вместо того, чтобы помещать «onfocus = ...» в HTML каждого текстового поля. Но хороший подход

екст. нет способа узнать, где находится фокус AFAIK (может быть, взаимодействует со всеми узлами DOM?).

проверьте этот стекопоток - у него есть решение для вас: Как узнать, какой элемент DOM имеет фокус?

Добавление текста в текущей позиции курсора Обновление текущей позиции курсора

Демо:https: //codepen.io/anon/pen/qZXmg

Испытано в Chrome 48, Firefox 45, IE 11 и 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>

текста в позиции курсора. Если пользователь выбрал текст, и вы хотите, чтобы этот текст был заменен (по умолчанию используется большинство текста), вам нужно внести небольшое изменение при установке переменной 'back'.

Кроме того, если вам не требуется поддержка более старых версий IE, современные версии поддерживают textarea.selectionStart, поэтому вы можете удалить все обнаружение браузера и специфический для IE код.

Вот упрощенная версия, которая работает как минимум для Chrome и IE11 и обрабатывает замену выделенного текста.

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;
}
 xzdead10 окт. 2015 г., 10:56
Очень хорошо, спасиб

using @quick_sliv ответ:

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

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

Я написал это в ответ на Как добавить текст в текстовое поле с текущей позиции указателя с помощью jquery?

 MacroMan06 февр. 2014 г., 11:54
Очень просто по сравнению с другими. + 1
 AlfaTeK04 мая 2017 г., 19:40
Чтобы помочь, вот полное решение с восстановлением позиции каретки и заменой выбранной области вставленным содержимым: Jsfiddle.net / NaHTw / 1028
 silviomoreto24 июн. 2014 г., 20:51
даже лучше, если кешировать селектор: Jsfiddle.net / NaHTw / 304
 Bludwarf14 авг. 2015 г., 12:45
Вы также можете восстановить положение каретки после изменения значения с помощью:document.getElementById("txt").selectionStart = caretPos + txtToAdd.length.
 ruffin19 апр. 2016 г., 23:39
Ну что ж, если вы собираетесь зайти так далеко, удалив jQuery, то можете и удали все это. ; ^)

Этот плагин jQuery дает вам готовый способ выбора / манипулирования кареткой.

Content Editable, HTML или любой другой выбор элементов DOM

Если вы пытаетесь вставить в каретку на<div contenteditable="true">, это становится намного сложнее, особенно если в редактируемом контейнере есть дочерние элементы.

Мне очень повезло, используяСтройны библиотека:

GIT:https: //github.com/timdown/rangNPM:https: //www.npmjs.com/package/rang

У него есть масса замечательных функций, таких как:

Сохранение позиции или выделения Затем, Восстановите Позицию или Выбор Получите выбор HTML или Открытый текст Среди многих других

Последняя демонстрация, которую я проверял, не работала в режиме онлайн, однако в репозитории есть рабочие демо. Чтобы начать, просто загрузите репо из Git или NPM, затем откройте ./rangy/demos/index.htm

Это делает работу с Paret и выделение текста на одном дыхании!

Решение Вопроса

Во:

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>

 deFreitas05 мая 2016 г., 18:42
Рабочий пример Jsfiddle.net / deFreitas / 7s40cp1a / 1
 Fernando27 дек. 2014 г., 19:20
wwwooooo, спасибо !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Jeffrey Harmon05 февр. 2015 г., 21:37
Это отлично работает, но не поддерживает замену выделенного текста, как все текстовые редакторы. Это может не понадобиться для исходного вопроса автора, но если вам это нужно, вы можете просто заменить 'strPos' на 'txtArea.selectionEnd'. Мой ответ ниже показывает это, наряду с удалением кода обнаружения браузера, если вам не требуется поддержка более старых версий IE.
 haykam28 июл. 2016 г., 21:09
Есть ли способ выделить все элементы с помощьюareaId?
 Ahmad Alfy04 июн. 2013 г., 11:01
Могу я купить тебе пива? шутки в сторону

этот ответ.

Я досталgetElementById чтобы я мог ссылаться на элемент по-другому.

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: добавлен бегущий фрагмент,jQuery не используется.

 oliverseal26 дек. 2012 г., 08:26
element.focus() является допустимым методом JavaScript для DOMElements: W3schools.com / jsref / met_html_focus.asp
 Scott Stafford23 мая 2012 г., 05:18
Является ли элемент объектом jquery или нет? element.value и element.focus () не могут работать одновременно ...
 ar201504 мая 2018 г., 04:16
Лучшая идея - отказаться от совместимости с IE.
 Collin Anderson04 мая 2018 г., 15:33
Да, я написал этот ответ 7 лет назад. На данный момент IE 11 является хорошей поддерживаемой минимальной версией, и приведенный выше код работает там.

vaScript

Процес

Определить текущую позицию курсора Получите текст для копирования Установите текст там Обновить позицию курсора

У меня есть 2 текстовых поля и кнопка. Мне нужно нажать на определенную позицию в текстовом поле, а затем нажать на кнопку, чтобы вставить текст из другого текстового поля в положение предыдущего текстового поля.

Основная проблема заключается в том, что мы получаем текущую позицию курсора, куда мы будем вставлять текс

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

го, и обнаружение браузера не работает должным образом, он обнаружил @ Ф. (Firefox), когда я был в Internet Explorer.

Я только что сделал это изменение:

if ($.browser.msie) 

Вместо того

if (br == "ie") { 

В результате получается следующий код:

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

Ваш ответ на вопрос