繁体   English   中英

在光标使用 Javascript/jquery 的地方插入文本

[英]Inserting a text where cursor is using Javascript/jquery

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

例如,如果光标/焦点位于显示“apple”的文本框上,而他单击了显示“[email]”的链接,那么我希望该文本框显示“apple bob@example.com”。

我怎样才能做到这一点? 这甚至是可能的,因为如果焦点在单选/下拉/非文本框元素上怎么办? 可以记住最后一个关注文本框的内容吗?

使用这个,从这里

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

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

上面的代码在 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 is not being used

使用@quick_sliv 回答:

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

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

过程

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

这里我有 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>

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

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

演示: 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>

我认为您可以使用以下 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 并计算光标的位置,因此它可能更适合您的需求。 另一方面,如果这就是您要找的东西,它会更轻巧。

接受的答案在 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;
}

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

这个问题的答案是很久以前发布的,我是通过谷歌搜索偶然发现的。 HTML5 提供了包含setRangeText()方法的HTMLInputElement API ,该方法用新字符串替换<input><textarea>元素中的文本范围:

element.setRangeText('abc');

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

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

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

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

浏览器兼容性

setRangeText的 MDN 页面不提供浏览器兼容性数据,但我想它与HTMLInputElement.setSelectionRange()相同,它基本上是所有现代浏览器,IE 9 及更高版本,Edge 12 及更高版本。

您只能聚焦所需的文本框并在那里插入文本。 没有办法找出 AFAIK 的焦点在哪里(也许在所有 DOM 节点上进行交互?)。

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

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

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

我使用Rangy库真的很幸运:

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

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

上次我检查的在线演示没有工作,但是 repo 有工作演示。 首先,只需从 Git 或 NPM 下载 Repo,然后打开 ./rangy/demos/index.html

它使处理插入符号和文本选择变得轻而易举!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM