使用jQuery在文本区域中插入文本

158
我想知道如何使用jQuery在单击锚点标签时将文本插入到文本区域中。 我不想替换文本区域中已有的文本,而是要将新文本追加到文本区域后面。

1
如果这是解决方案 - 我更愿意自己构建它。这是为了我正在为朋友做的个人博客,所以任何适合的东西都可以。 - user114752
所以你想选择一个文本,无论选择哪个,都使用jQuery来填充一个文本区域,那么这个文本是从哪里来的,是手动输入还是来自特殊标签? - TStamper
TStamper,我想要能够点击一个按钮,根据所点击的内容将文本插入到文本区域中。 - user114752
我不太明白,所以如果你点击一个加粗的按钮,你想要在你的文本区域中出现加粗标签"<b>"吗? - TStamper
是的,如果你不理解也没关系,其他人也在帮我。 - user114752
显示剩余4条评论
17个回答

187

我喜欢jQuery函数扩展。然而,this指的是jQuery对象而不是DOM对象。所以我稍微修改了一下,使它变得更好(可以同时更新多个文本框/文本域)。

jQuery.fn.extend({
insertAtCaret: function(myValue){
  return this.each(function(i) {
    if (document.selection) {
      //For browsers like Internet Explorer
      this.focus();
      var sel = document.selection.createRange();
      sel.text = myValue;
      this.focus();
    }
    else if (this.selectionStart || this.selectionStart == '0') {
      //For browsers like Firefox and Webkit based
      var startPos = this.selectionStart;
      var endPos = this.selectionEnd;
      var scrollTop = this.scrollTop;
      this.value = this.value.substring(0, startPos)+myValue+this.value.substring(endPos,this.value.length);
      this.focus();
      this.selectionStart = startPos + myValue.length;
      this.selectionEnd = startPos + myValue.length;
      this.scrollTop = scrollTop;
    } else {
      this.value += myValue;
      this.focus();
    }
  });
}
});

这真的很有效。您可以一次插入多个位置,例如:

$('#element1, #element2, #element3, .class-of-elements').insertAtCaret('text');

3
答案中有一个尾随的}),所以起初我认为该解决方案不起作用,但修复后,在IE7和FF3.5上运行得很好。您可以在TEXTAREA元素的插入符号处插入一段文本。谢谢! - Philippe
1
这在Chrome中也有效。感谢节省了我的时间 :) 也感谢@Thinker提供的原始代码。 - Veli Gebrev
6
sel 的意思是全局的吗? - qwertymk
这似乎总是将我的文本发布在选择的末尾。这可能是因为在调用此方法之前从未编写selectionStart。 - Trip
1
对于任何想要CoffeeScript版本的人:https://gist.github.com/zachaysan/7100458 - zachaysan
显示剩余4条评论

131

根据Jason的评论,您可以尝试:

$('a').click(function() //this will apply to all anchor tags
{ 
   $('#area').val('foobar'); //this puts the textarea for the id labeled 'area'
})

编辑- 若要向文本添加内容,请查看下面的内容

$('a').click(function() //this will apply to all anchor tags
{ 
   $('#area').val($('#area').val()+'foobar'); 
})

检查我的答案,有一个更简单的方法来追加文本。 - Jason
8
抱歉,Jason说得不对。append期望以HTML元素开头的HTML数据,例如:<p>。 - TStamper
如果结果来自一个 PHP 页面并由 jQuery 处理,那怎么样?(在数据之间使用 Json 传输) - Abu Rayane

51

我在我的代码中使用了这个函数:

$.fn.extend({
  insertAtCaret: function(myValue) {
    this.each(function() {
      if (document.selection) {
        this.focus();
        var sel = document.selection.createRange();
        sel.text = myValue;
        this.focus();
      } else if (this.selectionStart || this.selectionStart == '0') {
        var startPos = this.selectionStart;
        var endPos = this.selectionEnd;
        var scrollTop = this.scrollTop;
        this.value = this.value.substring(0, startPos) +
          myValue + this.value.substring(endPos,this.value.length);
        this.focus();
        this.selectionStart = startPos + myValue.length;
        this.selectionEnd = startPos + myValue.length;
        this.scrollTop = scrollTop;
      } else {
        this.value += myValue;
        this.focus();
      }
    });
    return this;
  }
});
input{width:100px}
label{display:block;margin:10px 0}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Copy text from: <input id="in2copy" type="text" value="x"></label>
<label>Insert text in: <input id="in2ins" type="text" value="1,2,3" autofocus></label>
<button onclick="$('#in2ins').insertAtCaret($('#in2copy').val())">Insert</button>

这不是我自己的代码,我在某个地方通过谷歌搜索之后调整过来适用于我的应用。

使用方法: $('#element').insertAtCaret('text');


2
但是这个解决方案在用户将光标移动到其他位置时不起作用 :) 不管怎样,没关系。 - Thinker
3
你使用“this”作为一个包装集和一个元素。嗯...我试过了,如果没有修改是行不通的。 - Scott Evernden
5
我也无法让这个代码运行起来。我正在使用jQuery。我尝试了文本区域和文本框两种方式。我认为,例如 this.value 应该改成 this.val() 等等。 - Nick B
1
是的,在IE浏览器上,它一直插入在DOM的顶部,而在Firefox上则没有反应。使用最新版本的JQuery... - Caveatrob
你好,我尝试了这个,但完全不起作用。我使用的是Google Chrome浏览器。 - Ardee Aram
显示剩余3条评论

20

我知道这是一个老问题,但对于寻找解决方案的人来说,值得注意的是您不应该使用append()将内容添加到textarea中。 append()方法的目标是innerHTML而不是textarea的值。 内容可能出现在textarea中,但不会添加到元素的表单值中。

如上所述,使用:

$('#textarea').val($('#textarea').val()+'new content'); 

将正常工作。


13

这个函数允许你向文本框“注入”一段文字,所谓“注入”,就是将该段文字附加到光标所在位置。

function inyectarTexto(elemento,valor){
 var elemento_dom=document.getElementsByName(elemento)[0];
 if(document.selection){
  elemento_dom.focus();
  sel=document.selection.createRange();
  sel.text=valor;
  return;
 }if(elemento_dom.selectionStart||elemento_dom.selectionStart=="0"){
  var t_start=elemento_dom.selectionStart;
  var t_end=elemento_dom.selectionEnd;
  var val_start=elemento_dom.value.substring(0,t_start);
  var val_end=elemento_dom.value.substring(t_end,elemento_dom.value.length);
  elemento_dom.value=val_start+valor+val_end;
 }else{
  elemento_dom.value+=valor;
 }
}

你可以像这样使用它:

<a href="javascript:void(0);" onclick="inyectarTexto('nametField','hello world');" >Say hello world to text</a>

如果我们有“将标签插入文本”的功能,会更有趣且更有意义。

在所有浏览器中都可以使用。


6
因为非英文变量名而投反对票?实际上,这个回答仍然可以完全阅读。按下投票反对按钮应该是因为答案无助于解决问题,但这里不是这种情况。顺便说一句,当你投反对票时也会扣除你的声望分数。 - Josh M.
理解西班牙代码花了一些时间。而且这段代码存在一个错误。它总是插入到文本框的开头,而不是结尾。例如:如果文本是:“亲爱的用户”,在点击后它会在“亲爱的”之前插入,而不是在“用户”之后。 - Dev
@JoshM。问题是,这是一个重复的由Thinker编写的更旧和更完整的答案...他删除了一些.focus()调用以及修改后对selectionStartselectionEnd的更新。西班牙语变量可能已被用来证明另一个答案... - CPHPython

12

你好,这是一个修改后的版本,在我的Firefox中可以正常工作,并且在光标位置插入内容。

  $.fn.extend({
  insertAtCaret: function(myValue){
  var obj;
  if( typeof this[0].name !='undefined' ) obj = this[0];
  else obj = this;

  if ($.browser.msie) {
    obj.focus();
    sel = document.selection.createRange();
    sel.text = myValue;
    obj.focus();
    }
  else if ($.browser.mozilla || $.browser.webkit) {
    var startPos = obj.selectionStart;
    var endPos = obj.selectionEnd;
    var scrollTop = obj.scrollTop;
    obj.value = obj.value.substring(0, startPos)+myValue+obj.value.substring(endPos,obj.value.length);
    obj.focus();
    obj.selectionStart = startPos + myValue.length;
    obj.selectionEnd = startPos + myValue.length;
    obj.scrollTop = scrollTop;
  } else {
    obj.value += myValue;
    obj.focus();
   }
 }
})

10

你尝试过吗:

$("#yourAnchor").click(function () {
    $("#yourTextarea").val("your text");
});

不确定自动突出显示,尽管如此。

编辑:

追加:

$("#yourAnchor").click(function () {
    $("#yourTextarea").append("your text to append");
});

谢谢,我会尝试一下。我是jQuery的新手,所以不熟悉所有易于使用的函数。 - user114752
我也是相对较新的。一旦你掌握了它,它就会变得很有趣和超级简单。查看此链接以获取更多参考:http://docs.jquery.com/Main_Page - Jason
6
正如下面Marcus所指出的,append()方法不能在textarea的值上工作。append()方法针对的是innerHTML而不是textarea的值。 - Turadg

6
您要求的内容在jQuery中应该相对简单-
$(function() {
    $('#myAnchorId').click(function() { 
        var areaValue = $('#area').val();
        $('#area').val(areaValue + 'Whatever you want to enter');
    });
});

我能想到突出插入文本的最好方法是将其包装在具有CSS类的span中,并将background-color设置为您选择的颜色。在下一次插入时,您可以从任何现有的span中删除类(或剥离span)。
然而,市场上有很多免费的所见即所得HTML /富文本编辑器,我相信其中一个会符合您的需求。
- TinyMCE - JavaScript所见即所得编辑器 - 富文本编辑器 - YUI库 - 10个jQuery和非jQuery JavaScript富文本编辑器

5

这里有一个在jQuery 1.9+中可行的快速解决方案:

a) 获取插入符位置:

function getCaret(el) {
        if (el.prop("selectionStart")) {
            return el.prop("selectionStart");
        } else if (document.selection) {
            el.focus();

            var r = document.selection.createRange();
            if (r == null) {
                return 0;
            }

            var re = el.createTextRange(),
                    rc = re.duplicate();
            re.moveToBookmark(r.getBookmark());
            rc.setEndPoint('EndToStart', re);

            return rc.text.length;
        }
        return 0;
    };
b) 在插入符位置添加文本:
function appendAtCaret($target, caret, $value) {
        var value = $target.val();
        if (caret != value.length) {
            var startPos = $target.prop("selectionStart");
            var scrollTop = $target.scrollTop;
            $target.val(value.substring(0, caret) + ' ' + $value + ' ' + value.substring(caret, value.length));
            $target.prop("selectionStart", startPos + $value.length);
            $target.prop("selectionEnd", startPos + $value.length);
            $target.scrollTop = scrollTop;
        } else if (caret == 0)
        {
            $target.val($value + ' ' + value);
        } else {
            $target.val(value + ' ' + $value);
        }
    };

c) 示例

$('textarea').each(function() {
  var $this = $(this);
  $this.click(function() {
    //get caret position
    var caret = getCaret($this);

    //append some text
    appendAtCaret($this, caret, 'Some text');
  });
});

3

在Chrome 20.0.11中,它对我来说效果很好。

var startPos = this[0].selectionStart;
var endPos = this[0].selectionEnd;
var scrollTop = this.scrollTop;
this[0].value = this[0].value.substring(0, startPos) + myVal + this[0].value.substring(endPos, this[0].value.length);
this.focus();
this.selectionStart = startPos + myVal.length;
this.selectionEnd = startPos + myVal.length;
this.scrollTop = scrollTop;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接