在光标使用 Javascript/jquery 的位置插入文本

我有一页有很多文本框。当有人点击一个链接时,我希望在光标所在的位置插入一两个词,或者添加到具有焦点的文本框中。

例如,如果光标/焦点指向一个文本框,上面写着“ apple”,然后他点击一个链接,上面写着“[ email ]”,那么我希望文本框写着“ apple bob@example.com”。

我怎么能这么做?这有可能吗,因为如果焦点是单选/下拉/非文本框元素呢?最后关注的文本框能记住吗?

172198 次浏览

您只能对焦所需的文本框,并在其中插入文本。没有办法找出哪里的焦点是 AFAIK (也许在所有 DOM 节点上交互?).

检查这个堆栈溢出-它为你提供了一个解决方案: 如何找出哪个 DOM 元素具有焦点?

用这个,来自 给你:

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>

我认为你可以使用下面的 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')" />

以前的解决方案(支持 gclaghorn)使用 textarea 并计算光标的位置,因此它可能更适合您的需要。另一方面,如果你要找的是这个的话,这个会更轻。

上面的代码在 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

这个 jQuery 插件 为您提供了一种预制的选择/插入符号操作方法。

如何通过 JQuery 和 JavaScript 将一些文本插入到 TextBox 的当前光标位置

过程

  1. 查找当前光标位置
  2. 获取要复制的文本
  3. 把文本设置在那里
  4. 更新光标位置

这里我有两个文本框和一个按钮。我必须点击文本框上的某个位置,然后点击按钮粘贴文本 其他文本框到上一个文本框的位置。

这里的主要问题是,获得当前光标的位置,我们将粘贴文本。

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

接受的答案在 Internet Explorer 9上对我不起作用。 我检查了一下,发现浏览器检测没有正常工作,当我在 Internet Explorer 的时候它检测到了 是的(firefox)。

我刚做了这个改变:

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

也许短一点的版本更容易理解?

    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 从指针的当前位置向文本框添加文本?

George Claghorn 的批准答案对于简单地在光标位置插入文本非常有效。如果用户已经选择了文本,并且您希望替换该文本(大多数文本的默认体验) ,那么在设置“ 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;
}

将文本添加到当前光标位置涉及两个步骤:

  1. 在当前光标位置添加文本
  2. 更新当前光标位置

演示: https://codepen.io/anon/pen/qZXmgN

在 Chrome 48,Firefox 45,IE 11和 Edge 25中测试

约翰逊:

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>

使用@fast _ sliv 回答:

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

内容可编辑,HTML 或任何其他 DOM 元素选择

如果您试图在 <div contenteditable="true">上插入插入符号,这将变得更加困难,特别是当可编辑容器中有子容器时。

我在使用 兰吉库方面运气非常好:

它有很多很棒的功能,比如:

  • 保存位置或选择
  • 然后,恢复位置或选择
  • 获取所选 HTML 或 Plainttext
  • 还有很多

在线演示没有工作最后我检查,但是回购有工作演示。首先,从 Git 或 NPM 下载 Repo,然后打开。/range/demos/index.html

它使用插入符号和文本选择工作轻而易举!

这个问题的答案在很久以前就发布了,我是通过谷歌搜索偶然发现的。HTML5提供了包含 SetRangeText ()方法的 HTMLInputElement API,它将 <input><textarea>元素中的一系列文本替换为一个新的字符串:

element.setRangeText('abc');

以上将用 abc代替 element内部的选择。还可以指定要替换输入值的哪一部分:

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

以上将用 abc代替输入值的第4到第6个字符。还可以通过提供下列字符串之一作为第4个参数,指定在替换文本后如何设置选定内容:

  • 'preserve'尝试保留所选内容。这是默认值。
  • 'select'选择新插入的文本。
  • 'start'将选定内容移动到插入的文本之前。
  • 'end'将选定内容移动到插入的文本之后。

浏览器兼容性

SetRangeText的 MDN 页面没有提供浏览器兼容性数据,但是我猜它和 SetSelectionRange ()是一样的,基本上都是现代浏览器,IE 9及以上,Edge 12及以上。