Вставка текста, где курсор использует Javascript/ JQuery
У меня есть страница с множеством текстовых полей. Когда кто-то нажимает на ссылку, я хочу, чтобы слово или два были вставлены туда, где находится курсор, или добавлены к текстовому полю с фокусом.
Например, если курсор / фокус находится на текстовом поле с надписью "яблоко", и он щелкает ссылку с надписью "[электронная почта]", то я хочу, чтобы в текстовом поле было написано "яблоко bob@example.com".
Как я могу это сделать? Возможно ли это вообще, так как что, если фокус находится на элементе radio/dropdown/non textbox? Можно ли запомнить последнее сосредоточенное на текстовом поле?
12 ответов
Используйте это отсюда:
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>
Может быть, более короткая версия, было бы легче понять?
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?
Одобренный ответ Джорджа Клагхорна отлично подошел для простой вставки текста в позиции курсора. Однако, если пользователь выбрал текст, и вы хотите, чтобы этот текст был заменен (по умолчанию для большинства текста), вам нужно внести небольшое изменение при установке переменной '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;
}
Код выше не работал для меня в IE. Вот код, основанный на этом ответе.
Я достал 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>
РЕДАКТИРОВАТЬ: Добавлен работающий фрагмент, jQuery не используется.
Используя ответ @quick_sliv:
function insertAtCaret(el, text) {
var caretPos = el.selectionStart;
var textAreaTxt = el.value;
el.value = textAreaTxt.substring(0, caretPos) + text + textAreaTxt.substring(caretPos);
};
Как вставить текст в текущую позицию курсора TextBox через JQuery и JavaScript
Процесс
- Найти текущую позицию курсора
- Получить текст для копирования
- Установить текст там
- Обновить позицию курсора
Здесь у меня есть 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>
Добавление текста в текущую позицию курсора состоит из двух шагов:
- Добавление текста в текущей позиции курсора
- Обновление текущей позиции курсора
Демо: https://codepen.io/anon/pen/qZXmgN
Протестировано в 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>
Ответ на этот вопрос был опубликован так давно, и я наткнулся на него через поиск Google. HTML5 предоставляет API HTMLInputElement, который включает метод setRangeText(), который заменяет диапазон текста в<input>
или <textarea>
элемент с новой строкой:
element.setRangeText('abc');
Вышеупомянутое заменит выбор, сделанный внутри element
с abc
. Вы также можете указать, какую часть входного значения заменить:
element.setRangeText('abc', 3, 5);
Приведенное выше заменит с 4-го по 6-й символы входного значения на abc
. Вы также можете указать, как должен быть установлен выбор после замены текста, указав одну из следующих строк в качестве 4-го параметра:
'preserve'
пытается сохранить выделение. Это значение по умолчанию.'select'
выбирает только что вставленный текст.'start'
перемещает выделение непосредственно перед вставленным текстом.'end'
перемещает выделение сразу после вставленного текста.
Совместимость с браузером
Страница MDN для setRangeText не предоставляет данных о совместимости с браузером, но я предполагаю, что это будет то же самое, что и HTMLInputElement.setSelectionRange(), который в основном используется во всех современных браузерах, IE 9 и выше, Edge 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 и рассчитывает положение курсора, так что оно может быть лучше для того, что вы хотите. С другой стороны, этот будет более легким, если это то, что вы ищете.
Этот плагин jQuery дает вам готовый способ выбора / манипулирования кареткой.
Принятый ответ не работал для меня в Internet Explorer 9. Я проверил его, и обнаружение браузера не работает должным образом, он обнаружил ff (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;
}
Вы можете только сфокусировать нужное текстовое поле и вставить туда текст. нет никакого способа узнать, где находится фокус AFAIK (возможно, взаимодействующий по всем узлам DOM?).
проверьте этот стековый поток - у него есть решение для вас: как узнать, какой элемент DOM находится в фокусе?
Редактирование содержимого, выбор HTML или любого другого элемента DOM
Если вы пытаетесь вставить в каретку на <div contenteditable="true">
это становится намного сложнее, особенно если в редактируемом контейнере есть дочерние элементы.
Мне очень повезло с использованием библиотеки Rangy:
Он имеет массу замечательных функций, таких как:
- Сохранить позицию или выбор
- Затем, позже, восстановить позицию или выбор
- Получить выделенный HTML или обычный текст
- Среди многих других
Демонстрационная версия не работала в последний раз, когда я проверял, однако в репозитории есть рабочие демоверсии. Для начала просто загрузите репо из Git или NPM, а затем откройте./rangy/demos/index.html
Это делает работу с Paret Pos и выбор текста на одном дыхании!