我的页面上有很多文本框。当某人单击链接时,我希望在光标所在的位置插入一两个单词,或将其附加到具有焦点的文本框。例如,如果光标/焦点位于文本框上说“苹果”,然后他单击一个说“ [电子邮件]”的链接,然后我想在文本框中说“苹果bob@example.com”。

我该怎么做?如果焦点集中在radio / dropdown / non textbox元素上,该怎么办呢?可以记住上一个专注于文本框的内容吗?

评论

我认为这是可能的,因为它是WYSISYG编辑器的基础,我不知道该怎么做。

如何使用javascript在插入符号中插入字符?可能重复吗?

感谢您提出这个问题...现在,我可以使用我的Chrome扩展程序在光标处插入“ [version]”了!

如果您正在寻找一个具有撤消支持的简单模块,请尝试插入文本文本区域。如果需要IE8 +支持,请尝试使用光标插入文本包。

#1 楼

从这里使用它:




 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的较早版本,则以下我的答案将显示此内容以及删除浏览器检测代码。

–杰弗里·哈蒙(Jeffrey Harmon)
2015年2月5日在20:37

有没有办法选择所有具有areaId的元素?

– Haykam
16年7月28日在19:09

您可以通过插入这样的功能来实现自动删除所选文本。函数deleteTxt(){var ele = document.getElementById('yourTextarea'); var text = ele.value; text = text.slice(0,ele.selectionStart)+ text.slice(ele.selectionEnd); ele.value =文字;返回文字; }

– NSTuttle
16-9-28在20:41

如何在鼠标位置插入文本?

– Thamarai T
19年5月14日下午5:22

你是最好的!

– Ecko Santoso
19年5月16日在17:58

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





我写这篇文章是为了回应如何使用jquery从指针的当前位置向文本框添加文本?

评论


您还可以在更改值后使用以下方法恢复插入符号位置:document.getElementById(“ txt”)。selectionStart = caretPos + txtToAdd.length。

–狂人
15年8月14日在10:45

为我工作,谢谢。仅供参考,jquery选择器$(“#”)不存在“ selectionStart”属性。您需要检查document.getElementById()

–乐高
2015年12月13日12:25



jsfiddle.net/NaHTw/802是您的解决方案,添加了一些额外功能,可以用粘贴内容替换所选区域

– patrick
15年12月20日在1:07

好吧,如果要进一步删除jQuery,则最好将其全部删除。 ; ^)

–松饼
16-4-19在21:39



只是为了提供帮助,这里是带有插入符号位置还原以及将所选区域替换为粘贴内容的完整解决方案:jsfiddle.net/NaHTw/1028

– AlfaTeK
17年5月4日在17:40

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


评论


这很好,但是没有考虑元素的最大长度,因此插入后的结果值可能会比最大长度长。

–mbomb007
19年5月3日在16:07



#4 楼

上面的代码不适用于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对象? element.value和element.focus()不能同时工作...

–斯科特·斯塔福德
2012年5月23日在3:18

element.focus()是DOMElements上的合法JavaScript方法:w3schools.com/jsref/met_html_focus.asp

–寡头
2012年12月26日在7:26

最好的主意是放弃IE兼容性。

–ar2015
18年5月4日在2:16

是的,我7年前写了这个答案。在这一点上,IE 11是一个很好的最低受支持版本,并且上面的代码可以在此处运行。

–科林·安德森
18年5月4日在13:33

#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的当前光标位置插入一些Text

Process


查找当前光标位置
获取文本被复制
在此处设置文本
更新光标位置

这里有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,因此具有特定类的每个文本框都将此事件应用于它们,而不必在每个文本框的html中放入“ onfocus = ...”。但是好的方法:)

–单击升级
09年6月30日在15:04

#9 楼

在Internet Explorer 9上,接受的答案对我不起作用。 >我只是做了这个更改:

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


#10 楼

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

#11 楼

您只能将所需的文本框聚焦,然后在其中插入文本。没有办法找出AFAIK的重点(可能是在所有DOM节点上进行交互吗?)。

检查此stackoverflow-它为您提供了一个解决方案:
如何找出哪个DOM元素具有焦点?

#12 楼

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

如果您尝试在<div contenteditable="true">上的插入符处插入,这会变得更加困难,尤其是在可编辑容器中有子对象的情况下。

我使用Rangy库非常幸运:


GIT:https://github.com/timdown/rangy

NPM: https://www.npmjs.com/package/rangy


它具有很多很棒的功能,例如:


保存位置或选择
然后再恢复位置或选择
获取选择HTML或纯文本
还有许多其他方法

我最后一次检查了在线演示,但是回购有工作演示。首先,只需从Git或NPM下载回购,然后打开./rangy/demos/index.html

,它使插入符号pos和文本选择的工作变得轻而易举!

#13 楼

这个问题的答案发布于很久以前,我通过Google搜索偶然发现了它。 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和更高版本。