web-dev-qa-db-ja.com

テキスト領域のカーソル位置にテキストを挿入します(Javascript)

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

93
JoshMWilliams
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;
    }
}
88
Raab

このスニペットは、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);
});
68
Adriano Alves

適切な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;
  }
};
26
Erik Aigner

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を最初のパラメーターとして渡します。

これを行うための最もエレガントな方法ではありませんが、非常に簡単です。

12
Jayant Bhawal

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

私は単純な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

8
Erik Pukinskis

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

以下は 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);
  }
}

TriggerEvent関数の plainjs.com の功績

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

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

4
Jette

Firefox、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でのみサポートされています。

他のブラウザには、現在フォーカスされているhtml要素にのみ影響する「insertText」コマンドがあり、setRangeTextと同じ動作をします。

これに部分的に触発された 記事

4
Ramast
 /**
 * 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();
    }
})
1
zaarour

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

独自の参照用に変更された関数をポストします。この例では、<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)
}
0
Alexiy