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

时间:2009-06-30 14:47:42

标签: javascript jquery

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

例如,如果光标/焦点在文本框上说'apple'并且他点击了一个'[email]'的链接,那么我希望文本框说'apple bob@example.com'。

我该怎么做?这是否可能,因为如果重点是收音机/下拉/非文本框元素怎么办?可以记住最后关注文本框吗?

13 个答案:

答案 0 :(得分:229)

使用此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>

答案 1 :(得分:144)

也许更短的版本,会更容易理解?

    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?

时写的

答案 2 :(得分:39)

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

答案 3 :(得分:20)

上面的代码在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();
  }
}
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

答案 4 :(得分:6)

使用@quick_sliv回答:

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

答案 5 :(得分:4)

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

过程

  1. 查找当前光标位置
  2. 获取要复制的文本
  3. 将文字设置在那里
  4. 更新光标位置
  5. 这里我有2个TextBoxes和一个Button。我必须单击文本框上的某个位置,然后单击按钮以粘贴文本框中的文本 其他文本框到上一个文本框的位置。

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

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

答案 6 :(得分:2)

我认为您可以使用以下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并计算光标的位置,因此它可能更适合你想要的。另一方面,如果你正在寻找的话,这个会更轻巧。

答案 7 :(得分:2)

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

  1. 在当前光标位置添加文本
  2. 更新当前光标位置
  3. 演示: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 :(得分:1)

This jQuery plugin为您提供预先选择/插入操作的方法。

答案 9 :(得分:1)

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

答案 10 :(得分:0)

你只能将所需的文本框重点放在那里插入文本。没有办法找出AFAIK的重点(可能是在所有DOM节点上进行交互?)。

检查此stackoverflow - 它有一个解决方案: How do I find out which DOM element has the focus?

答案 11 :(得分:0)

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

如果您尝试在<div contenteditable="true">处插入插入符号,则会变得更加困难,尤其是在可编辑容器中有子项时。

我使用 Rangy 库真的好运:

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

  • 保存位置或选择
  • 然后,恢复位置或选择
  • 获取选择HTML或纯文本
  • 其他许多

最后我检查了在线演示没有工作,但是repo有工作演示。要开始使用,只需从Git或NPM下载Repo,然后打开./rangy/demos/index.html

这使得使用插入符号和文本选择变得轻而易举!

答案 12 :(得分:0)

这个问题的答案发布很久以前,我通过Google搜索偶然发现了它。 HTML5提供了包含HTMLInputElement API方法的setRangeText(),该方法用新的字符串替换了<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及以上。