JavaScriptでテキストエリア内の選択範囲の文字列を取得する方法

f:id:tsubasa123:20170119171032j:plain

こんにちは、つばさ(@tsubasa123)です。

次のカスタマイズに向けて調べたことをメモしておきます。思ったよりめんどくさいことしないといけなくて最初は戸惑いましたが、まぁやってることは簡単です。jQueryも使っていますが、別になくてもDOM操作ができれば問題ありません。

開始位置と終了位置から抜きとる

見出しの通り、テキストエリア内の全文から、選択範囲を抜き取るようにして文字列を取得することができます。

const getSelectArea = () => {
const val = $('textarea').val(),
elm = $('text').get(0),
tmp = {
before: val.slice(0, elm.selectionStart),
after: val.slice(elm.selectionEnd),
text: elm.value.slice(elm.selectionStart, elm.selectionEnd),
};
return tmp;
};
console.log(getSelectArea().text); // 選択範囲を表示

DOM要素が持つselectionStartselectionEndというプロパティを利用して文字列操作を行っています。古いIEではおそらく使えないプロパティですが、今回はIE無視でOKなのでセーフ。

今回は選択範囲までの文字列と、選択範囲の文字列と、選択範囲から後ろの文字列をそれぞれ取得するようにしました。これにより、

const getSelectArea = () => {
const val = $('textarea').val(),
elm = $('text').get(0),
tmp = {
before: val.slice(0, elm.selectionStart),
after: val.slice(elm.selectionEnd),
text: elm.value.slice(elm.selectionStart, elm.selectionEnd),
};
return tmp;
};
let sel = getSelectArea()
let txt = '<p class="hoge">' + sel.text + '</p>';
$('textarea').val(sel.before + txt + sel.after);

このように、選択範囲の前後に文字列を追加したりすることができるようになります。これがやりたかったので、選択範囲の文字列だけでなく、その前後も保持する形にしました。文字列だけ取得して処理を行いたい場合は前後の文字列は特に保持する必要はないと思います。

input[type=“text”]でも使える

textareaだけだと思ったら、inputタグでも使えました。

const getSelectArea = () => {
const val = $('input[type="text"]').val(),
elm = $('input[type="text"]').get(0),
tmp = {
before: val.slice(0, elm.selectionStart),
after: val.slice(elm.selectionEnd),
text: elm.value.slice(elm.selectionStart, elm.selectionEnd),
};
return tmp;
};

これでよし。これだけだと微妙なんですが、クリックイベントなどと併用して動的に選択範囲を作成すると便利に使えるかもしれません。

const getSelectArea = () => {
const val = $('input[type="text"').val(),
elm = $('input[type="text"').get(0),
tmp = {
before: val.slice(0, elm.selectionStart),
after: val.slice(elm.selectionEnd),
text: elm.value.slice(elm.selectionStart, elm.selectionEnd),
};
return tmp;
};
$('#btn').on('click', function() {
$('input[type="text"').get(0).focus();
$('input[type="text"').get(0).setSelectionRange(0, 10);
console.log(getSelectArea());
});

このようにすれば、特定の要素内の文字列の任意の場所を選択させることができます。便利そうではあるんですが、ちょっといい例が思い浮かびません。思いついたら追記します。

さいごに

とりあえず、テキストエリアの選択範囲を取得することを覚えました。今度はこれを応用してブログのカスタマイズに活かしていきたいと思います。

ではでは、最後までお付き合いいただきありがとうございました。