在光标位置将文本插入textarea(Javascript)

时间:2012-06-18 04:37:32

标签: javascript textarea

我想创建一个简单的函数,将文本添加到用户光标位置的文本区域。它需要是一个干净的功能。只是基础知识。我可以弄明白其余的。

13 个答案:

答案 0 :(得分:83)

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

答案 1 :(得分:65)

这个代码片段可以帮助您使用jQuery 1.9+的几行:http://jsfiddle.net/4MBUG/2/

$('input[type=button]').on('click', function() {
    var cursorPos = $('#text').prop('selectionStart');
    var v = $('#text').val();
    var textBefore = v.substring(0,  cursorPos);
    var textAfter  = v.substring(cursorPos, v.length);

    $('#text').val(textBefore + $(this).val() + textAfter);
});

答案 2 :(得分:26)

为了正确的Javascript

HTMLTextAreaElement.prototype.insertAtCaret = function (text) {
  text = text || '';
  if (document.selection) {
    // IE
    this.focus();
    var sel = document.selection.createRange();
    sel.text = text;
  } else if (this.selectionStart || this.selectionStart === 0) {
    // Others
    var startPos = this.selectionStart;
    var endPos = this.selectionEnd;
    this.value = this.value.substring(0, startPos) +
      text +
      this.value.substring(endPos, this.value.length);
    this.selectionStart = startPos + text.length;
    this.selectionEnd = startPos + text.length;
  } else {
    this.value += text;
  }
};

答案 3 :(得分:11)

对Erik Pukinskis的回答的纯JS修改:

function typeInTextarea(el, newText) {
  var start = el.selectionStart
  var end = el.selectionEnd
  var text = el.value
  var before = text.substring(0, start)
  var after  = text.substring(end, text.length)
  el.value = (before + newText + after)
  el.selectionStart = el.selectionEnd = start + newText.length
  el.focus()
}
  

仅在Chrome 47中测试过。

如果要在同一字段中键入时更改当前所选文本的值(对于自动完成或类似效果),请将document.activeElement作为第一个参数传递。

这不是最优雅的方式,但它非常简单。

答案 4 :(得分:8)

我喜欢简单的javascript,而且我通常都有jQuery。这是我提出的,基于mparkuk's

function typeInTextarea(el, newText) {
  var start = el.prop("selectionStart")
  var end = el.prop("selectionEnd")
  var text = el.val()
  var before = text.substring(0, start)
  var after  = text.substring(end, text.length)
  el.val(before + newText + after)
  el[0].selectionStart = el[0].selectionEnd = start + newText.length
  el.focus()
}

$("button").on("click", function() {
  typeInTextarea($("textarea"), "some text")
  return false
})

以下是演示:http://codepen.io/erikpukinskis/pen/EjaaMY?editors=101

答案 5 :(得分:8)

Rab的答案效果很好,但不适用于Microsoft Edge,所以我也为Edge添加了一个小的改编:

https://jsfiddle.net/et9borp4/

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 

      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 

      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

答案 6 :(得分:4)

如果用户在插入文本后未触摸输入,则输入'事件永远不会被触发,并且value属性不会反映更改。因此,以编程方式插入文本后触发输入事件非常重要。关注这个领域是不够的。

以下是Snorvarg's answer的副本,最后带有输入触发器:

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 

      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 

      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
    triggerEvent(myField,'input');
}

function triggerEvent(el, type){
  if ('createEvent' in document) {
    // modern browsers, IE9+
    var e = document.createEvent('HTMLEvents');
    e.initEvent(type, false, true);
    el.dispatchEvent(e);
  } else {
    // IE 8
    var e = document.createEventObject();
    e.eventType = type;
    el.fireEvent('on'+e.eventType, e);
  }
}

对于{011}触发了triggerEvent函数

有关plainjs.com

上的oninput事件的更多信息

我在为聊天创建表情符号选择器时发现了这一点。如果用户只选择几个表情符号并点击"发送"按钮,用户永远不会触摸输入字段。当检查value属性时,它始终为空,即使插入的表情符号unicodes在输入字段中可见。事实证明,如果用户没有触摸该字段,则输入'事件永远不会被解雇,解决方案是像这样触发它。花了很长时间才弄明白这个...希望能省一些时间。

答案 7 :(得分:2)

一个简单的解决方案可以在Firefox,Chrome,Chrome,Opera,Safari和Edge上使用,但可能无法在旧的IE浏览器上使用。

  var target = document.getElementByID("mytextarea_id")

  if (target.setRangeText) {
     //if setRangeText function is supported by current browser
     target.setRangeText(data)
  } else {
    target.focus()
    document.execCommand('insertText', false /*no UI*/, data);
  }
}

setRangeText函数允许您用提供的文本替换当前选择,或者如果没有选择,则将文本插入光标位置。据我所知,只有Firefox支持。

对于其他浏览器,存在“ insertText”命令,该命令仅影响当前集中的html元素,并且具有与setRangeText相同的行为

部分受此article

的启发

答案 8 :(得分:2)


function insertAtCaret(text) {
  const textarea = document.querySelector('textarea')
  textarea.setRangeText(
    text,
    textarea.selectionStart,
    textarea.selectionEnd,
    'end'
  )
}

setInterval(() => insertAtCaret('Hello'), 3000)
<textarea cols="60">Stack Overflow Stack Exchange Starbucks Coffee</textarea>

答案 9 :(得分:1)

 /**
 * Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz"
 */
String.prototype.insertInside = function(start, delCount, newSubStr) {
    return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
};


 $('textarea').bind("keydown keypress", function (event) {
   var val = $(this).val();
   var indexOf = $(this).prop('selectionStart');
   if(event.which === 13) {
       val = val.insertInside(indexOf, 0,  "<br>\n");
       $(this).val(val);
       $(this).focus();
    }
})

答案 10 :(得分:0)

将其更改为getElementById(myField)

 function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        document.getElementById(myField).focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    //MOZILLA and others
    else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
        var startPos = document.getElementById(myField).selectionStart;
        var endPos = document.getElementById(myField).selectionEnd;
        document.getElementById(myField).value = document.getElementById(myField).value.substring(0, startPos)
            + myValue
            + document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
    } else {
        document.getElementById(myField).value += myValue;
    }
}

答案 11 :(得分:0)

发布修改后的功能供自己参考。此示例插入<select>对象中的选定项,并将插入符号放在标记之间:

//Inserts a choicebox selected element into target by id
function insertTag(choicebox,id) {
    var ta=document.getElementById(id)
    ta.focus()
    var ss=ta.selectionStart
    var se=ta.selectionEnd
    ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length)
    ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2)
}

答案 12 :(得分:0)

下面的代码是Dmitriy Kubyshkin对https://github.com/grassator/insert-text-at-cursor软件包的TypeScript改编。

tweet_details=ratedogsimage[['tweet_id','rating_numerator', 'rating_denominator','name','p1', 'p1_conf', 'p1_dog', 'p2', 'p2_conf', 'p2_dog', 'p3', 'p3_conf', 'p3_dog'  ]]


with open('tweet-json copy') as outfile:

    for index, row in tweet_details.iterrows():
        for line in outfile:
            twitter  = json.loads(line)

            if str(row.tweet_id) == twitter['id_str']:

                tweet_id = twitter['id_str']
                retweet_count = twitter['retweet_count']
                favorite_count = twitter['favorite_count']
                followers_count = twitter['user']['followers_count']

                tweet_details.loc[index, 'retweet_count'] = retweet_count
                tweet_details.loc[index, 'favorite_count'] = favorite_count
                tweet_details.loc[index, 'followers_count'] = followers_count

        tweet_details = tweet_details.append(pd.DataFrame([[retweet_count, favorite_count, followers_count]],
                                        columns=['retweet_count', 'favorite_count', 'followers_count']), sort = False)

tweet_details = tweet_details.reset_index(drop=True)
tweet_details