firefoxがdocument.queryCommandSupported('insertText')に対してtrueを返してくるのに
実際には動作しない件について、
この場合はUndoは効かないもののとりあえずキャレット位置を分割して文字を挿入するようにし、
それ以外はdocument.execCommandを利用するパターン。
※そもそもexecCommandが非推奨ではあるんだけども、とりあえず。(調べたけど「navigator.clipboard.writeText」を使うしかない?ようだけどクリップボードが汚れるのが嫌)
$(function(){
//ボタン.btnクリック時、入力欄#hoge に テキスト「XXX 」を挿入する
$('.btn').on('click',function(event){
insertText('hoge','XXX');
});
});
function insertText(id,text){
let userAgent = window.navigator.userAgent;
let area = document.getElementById(id);
let flag = true;
event.preventDefault();
area.focus();
switch (true) {
case userAgent.indexOf('Firefox') != -1:
case document.queryCommandSupported('insertText') == false:
flag = false;
break;
}
if (flag) {
document.execCommand('insertText', false, text);
}else {
let ss = area.selectionStart;
let se = area.selectionEnd;
area.value = area.value.substr(0, ss) + text + area.value.substr(ss);
area.selectionEnd = se + text.length;
}
}
個人的には、.btnのdata属性で、挿入先IDとテキストを仕込む仕様が拡張性高くて好きです。
なお、document.execCommandの完全な代替を目指す場合、
valueに直接、挿入後のテキスト全体を入れる分岐をメインとして
「lastTextとして元のテキストを保持し、Undo時にそれを差し替える(Redo時も類似の処理)」実装を行なうことで
擬似的に対応可能だとは思いますが、
keydown時も含めて履歴を取らねば完全な代替とはいかず、誰かがまるっといい感じのコードを書いてくれることを期待します…