ユーザーのカーソル位置のテキスト領域にテキストを追加する単純な関数を作成したいと思います。きれいな機能である必要があります。基本だけです。残りを理解することができます。
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;
}
}
このスニペットは、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);
});
適切な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;
}
};
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
を最初のパラメーターとして渡します。
これを行うための最もエレガントな方法ではありませんが、非常に簡単です。
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;
}
}
私は単純な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
テキストが挿入された後にユーザーが入力に触れない場合、「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イベントの詳細
チャット用の絵文字ピッカーを作成中にこれを発見しました。ユーザーがいくつかの絵文字を選択して「送信」ボタンを押すだけで、ユーザーが入力フィールドに触れることはありません。入力された絵文字のユニコードが入力フィールドに表示されていても、値属性をチェックするときは常に空でした。ユーザーがフィールドに触れない場合、「入力」イベントは発生せず、解決策はこのようにトリガーすることでした。これを理解するのにかなり時間がかかりました...誰かの時間を節約できることを願っています。
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
と同じ動作をします。
これに部分的に触発された 記事
/**
* 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();
}
})
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;
}
}
独自の参照用に変更された関数をポストします。この例では、<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)
}