在光标使用 Javascript/jquery 的位置插入文本
Posted
技术标签:
【中文标题】在光标使用 Javascript/jquery 的位置插入文本【英文标题】:Inserting a text where cursor is using Javascript/jquery 【发布时间】:2010-11-07 00:54:22 【问题描述】:我有一个包含很多文本框的页面。当有人单击链接时,我希望在光标所在的位置插入一两个词,或附加到具有焦点的文本框。
例如,如果光标/焦点位于显示“apple”的文本框上,并且他单击显示“[email]”的链接,那么我希望文本框显示“apple bob@example.com”。
我该怎么做?这甚至可能吗,因为如果焦点在单选/下拉/非文本框元素上怎么办?可以记住最后一个关注的文本框吗?
【问题讨论】:
我认为这是可能的,因为它是所见即所得编辑器的基础,我不知道该怎么做。 How do I insert a character at the caret with javascript?的可能重复 感谢您提出这个问题...现在我可以使用 Chrome 扩展程序在光标处插入“[version]”! 如果您正在寻找一个支持撤消的简单模块,请尝试insert-text-textarea。如果您需要 IE8+ 支持,请尝试使用 insert-text-at-cursor 包。 【参考方案1】:使用这个,来自here:
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>
【讨论】:
这很好用,但它不能像所有文本编辑器那样处理替换选定的文本。发帖人的原始问题可能不需要这个,但如果你需要它,你可以简单地将'strPos'替换为'txtArea.selectionEnd'。如果您不需要支持旧版本的 IE,我在下面的回答会显示这一点,并删除浏览器检测代码。 有没有办法用areaId
选择所有元素?
您可以通过插入这样的功能来实现自动删除选定的文本。 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;
如何在鼠标位置插入文字?
你是最棒的!【参考方案2】:
也许一个更短的版本,会更容易理解?
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" />
我写这个是为了回复How to add a text to a textbox from the current position of the pointer with jquery?
【讨论】:
您还可以在更改值后恢复插入符号位置:document.getElementById("txt").selectionStart = caretPos + txtToAdd.length
。
为我工作,谢谢。仅供参考,通过 jquery 选择器 $("#") 不存在“selectionStart”属性。你需要通过 document.getElementById()
jsfiddle.net/NaHTw/802 是您的解决方案,添加了一些额外内容以将所选区域替换为粘贴的内容
好吧,如果您打算移除 jQuery,您不妨remove it all。 ;^)
只是为了提供帮助,这里是完整的解决方案,包括插入符号位置恢复以及用粘贴的内容替换选定区域:jsfiddle.net/NaHTw/1028【参考方案3】:
George Claghorn 批准的答案非常适合在光标位置简单地插入文本。如果用户选择了文本,并且您希望替换该文本(大多数文本的默认体验),则需要在设置“后退”变量时进行一些小的更改。
另外,如果你不需要支持旧版本的 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;
【讨论】:
这很好,但它没有考虑元素的maxlength
,因此插入后的结果值可能比最大值长。【参考方案4】:
上面的代码在 IE 中对我不起作用。这是一些基于this answer的代码。
我取出了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();
inputwidth:100px
labeldisplay: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>
编辑:添加了一个正在运行的 sn-p,jQuery 没有被使用。
【讨论】:
元素是否是 jquery 对象? element.value 和 element.focus() 不能同时工作...element.focus()
是 DOMElements 上的合法 JavaScript 方法:w3schools.com/jsref/met_html_focus.asp
最好的办法是放弃 IE 兼容性。
是的,我在 7 年前写了这个答案。此时 IE 11 是一个很好的最低支持版本,上面的代码在那里工作。【参考方案5】:
使用@quick_sliv 回答:
function insertAtCaret(el, text)
var caretPos = el.selectionStart;
var textAreaTxt = el.value;
el.value = textAreaTxt.substring(0, caretPos) + text + textAreaTxt.substring(caretPos);
;
【讨论】:
我发现的最简单的答案,效果很好!这应该是公认的答案。【参考方案6】:如何通过 JQuery 和 JavaScript 在 TextBox 的当前光标位置插入一些文本
过程
-
查找当前光标位置
获取要复制的文本
在那边设置文本
更新光标位置
这里我有 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>
【讨论】:
【参考方案7】:将文本添加到当前光标位置涉及两个步骤:
-
在当前光标位置添加文本
更新当前光标位置
演示: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>
【讨论】:
【参考方案8】:我认为您可以使用以下 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 并计算光标的位置,因此它可能更适合您想要的。另一方面,如果您正在寻找,这个会更轻量级。
【讨论】:
好主意。我使用了 jquery,因此每个具有特定类的文本框都将此事件应用于它们,而不必将“onfocus = ...”放在每个文本框的 html 中。但是好的方法:)【参考方案9】:这个问题的答案是很久以前发布的,我通过谷歌搜索偶然发现了它。 HTML5 提供了包含setRangeText() 方法的HTMLInputElement API,该方法将<input>
或<textarea>
元素中的一系列文本替换为新字符串:
element.setRangeText('abc');
以上内容会将element
中的选择替换为abc
。您还可以指定要替换输入值的哪一部分:
element.setRangeText('abc', 3, 5);
上面将用abc
替换输入值的第 4 到第 6 个字符。您还可以通过提供以下字符串之一作为第 4 个参数来指定在替换文本后应如何设置选择:
'preserve'
尝试保留选择。这是默认设置。
'select'
选择新插入的文本。
'start'
将所选内容移动到插入文本之前。
'end'
将所选内容移动到插入的文本之后。
浏览器兼容性
setRangeText 的 MDN 页面没有提供浏览器兼容性数据,但我猜应该和HTMLInputElement.setSelectionRange() 一样,基本上都是现代浏览器,IE 9 及以上,Edge 12 及以上。
【讨论】:
您链接的“setRangeText”mozilla 页面现在底部有一个“浏览器兼容性”部分:不支持 IE,但其他所有现代浏览器(Chrome、FF、Edge 等)都支持.要完全回答操作员的问题,这里有一些附加信息:您可以使用element.selectionStart
和 element.selectionEnd
来查找光标的位置。如果 start!=end,那么用户标记了一些文本,否则它只是光标的位置。 “0”表示在文本元素的最开始,如果有换行符(例如在文本区域中),它会继续计数。
一些更多信息,因为我已经完成了所有测试:我建议使用end
以获得最“自然”的感觉:光标放在插入文本的末尾,这使得它成为可能在一行中插入多个内容,而无需移动光标。它还允许替换已经存在的文本,之后,与preserve
不同,它不会选择之前选择的“从到”,而是再次将光标放在插入文本的末尾。 Windows 就是这样做的(不是 100% 确定 macOS 或 Linux),我真的很惊讶它不是默认设置。【参考方案10】:
接受的答案在 Internet Explorer 9 上对我不起作用。 我检查了它,浏览器检测没有正常工作,当我在 Internet Explorer 时它检测到 ff (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;
【讨论】:
【参考方案11】:This jQuery plugin 为您提供了一种预制的选择/插入符号操作方式。
【讨论】:
【参考方案12】:您只能聚焦所需的文本框并在那里插入文本。没有办法找出AFAIK的焦点在哪里(也许在所有DOM节点上进行交互?)。
检查此 *** - 它为您提供了解决方案: How do I find out which DOM element has the focus?
【讨论】:
【参考方案13】:内容可编辑、HTML 或任何其他 DOM 元素选择
如果您尝试在 <div contenteditable="true">
上插入插入符号,这将变得更加困难,尤其是当可编辑容器中有子项时。
使用 Rangy 库我真的很幸运:
GIT:https://github.com/timdown/rangy NPM:https://www.npmjs.com/package/rangy它有很多很棒的功能,例如:
保存位置或选择 然后,恢复位置或选择 获取选择的 HTML 或纯文本 还有很多我上次检查的在线演示无法正常工作,但是 repo 有工作演示。要开始使用,只需从 Git 或 NPM 下载 Repo,然后打开 ./rangy/demos/index.html
它使使用插入符号位置和文本选择变得轻而易举!
【讨论】:
以上是关于在光标使用 Javascript/jquery 的位置插入文本的主要内容,如果未能解决你的问题,请参考以下文章
Javascript(jQuery)在拖动项目时禁用页面滚动
有没有办法改变owl-carousel的光标? (不是 owl-dots 或 owl-nav)
在 javascript/jquery 中使用 PHP print_r 数组