162

ユーザーのカーソル位置のテキスト領域にテキストを追加する単純な関数を作成したいと思います。クリーンな関数である必要があります。基本だけ。私は残りを理解することができます。

4

13 に答える 13

143

selectionStart入力要素の/selectionEnd プロパティを使用する(<textarea>同様に機能する)

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;
    }
}
于 2012-06-18T04:44:42.477 に答える
95

このスニペットは、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);
});
于 2013-05-31T02:05:09.473 に答える
44

新しい答え:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText

ただし、これに対するブラウザのサポートについてはわかりません。

Chrome 81 でテスト済み。

function typeInTextarea(newText, el = document.activeElement) {
  const [start, end] = [el.selectionStart, el.selectionEnd];
  el.setRangeText(newText, start, end, 'select');
}

document.getElementById("input").onkeydown = e => {
  if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>
<div>It'll replace a selection with the given text.</div>

古い答え:

Erik Pukinskis の回答の純粋な JS 修正:

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

document.getElementById("input").onkeydown = e => {
  if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>

Chrome 47、81、および Firefox 76 でテスト済み。

同じフィールドに入力しているときに現在選択されているテキストの値を変更したい場合 (オートコンプリートまたは同様の効果のために)、document.activeElement最初のパラメーターとして渡します。

これは最も洗練された方法ではありませんが、非常に簡単です。

使用例:

typeInTextarea('hello');
typeInTextarea('haha', document.getElementById('some-id'));
于 2015-12-14T23:36:33.227 に答える
11

私は単純なjavascriptが好きで、通常はjQueryを使用しています。mparkukに基づいて、私が思いついたものは次のとおりです。

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

于 2015-04-25T07:20:14.203 に答える
5

テキストが挿入された後にユーザーが入力に触れない場合、'input' イベントはトリガーされず、value 属性は変更を反映しません。したがって、プログラムでテキストを挿入した後に入力イベントをトリガーすることが重要です。フィールドを集中させるだけでは不十分です。

以下は、最後に入力トリガーがあるSnorvarg の回答のコピーです。

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

triggerEvent 関数については、plainjs.comの功績によるものです

w3schools.com のoninputイベントの詳細

チャット用の絵文字ピッカーを作成しているときに、これを発見しました。ユーザーがいくつかの絵文字を選択して「送信」ボタンを押すだけの場合、ユーザーは入力フィールドに触れることはありません。value 属性を確認すると、挿入された絵文字 Unicode が入力フィールドに表示されていても、常に空でした。ユーザーがフィールドに触れない場合、「入力」イベントは発生せず、解決策はこのようにトリガーすることでした。これを理解するのにかなりの時間がかかりました...誰かの時間を節約できることを願っています.

于 2017-12-16T23:03:06.140 に答える
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)
}
于 2016-09-03T07:48:43.783 に答える