by WebSurfer
9. January 2012 23:04
JavaScript を使って textarea のキャレット(カーソル)位置に文字列を挿入するサンプルです。
挿入する文字列を入力するために jQuery UI の dialog を利用していますが、それ以外は JavaScript のみを使用しています。
Firefox などの場合は、選択された部分の先頭、末尾の index (整数型)を、それぞれ selectionStart、selectionEnd で取得できますが、IE の場合はそれに該当するプロパティがないのが問題です。
IE の場合は、document.selection プロパティで selection オブジェクト(textarea 要素そのものではなく、textarea 要素の中の選択された文字の部分)を取得し、さらに createRange メソッドを使って TextRange オブジェクトを作成し、それを操作することになります。
TextRange オブジェクトについては、MSDN ライブラリの TextRangeオブジェクトの使用 を参照してください。
そのサンプルコードは以下の通りです。上の画像は、このコードを実行したときのブラウザの画面です。実際に動かして試せるよう 実験室 にアップしましたので、興味のある方は試してみてください。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>textarea のキャレット位置に文字列を挿入</title>
<script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>
<link href="css/smoothness/jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
//<![CDATA[
// IE の場合、[ダイアログ表示]ボタンクリックの時点で
// textarea 内の選択された文字部分の TextRange オブジェ
// クトを取得して維持しておく。そうしないと、textbox に
// 入力中に textarea からフォーカスが外れ、選択範囲がリ
// セットされてしまう。
// Firefox 等は textarea からフォーカスが外れても、選択
// 範囲は維持されるので、このような処置は不要。
var textRange = null;
function getTextRange(textarea) {
// textarea の文字が選択されてない場合はフォーカスを
// 当てないとうまくいかない。
textarea.focus();
// document.selection プロパティで selection オブジ
// ェクト(testarea の中の選択された文字の部分)を取
// 得する。文字が選択されていない場合、キャレット位
// 置の空の selection オブジェクトになる。
// selection オブジェクトに何か処理を行う場合は、
// createRange メソッドで TextRange オブジェクトを作
// 成して処理する。
return document.selection.createRange();
}
function insertText(textarea, txt) {
if (textRange == null) {
// IE 以外の場合
// 選択部分の先頭の index と長さを取得
var index = textarea.selectionStart;
var length = textarea.selectionEnd - index;
// 文字列を挿入
textarea.value = textarea.value.substr(0, index) +
txt + textarea.value.substr(index + length);
// キャレット位置を挿入した文字列の最後尾に移動
textarea.focus();
var newCaretPosition = index + txt.length;
textarea.setSelectionRange(
newCaretPosition, newCaretPosition);
} else {
// IE の場合
// TextRange.text プロパティにダイアログの文字列を
// 設定し、testarea の中の選択された文字部分を置き
// 換える。
textRange.text = txt;
// キャレット位置を挿入した文字列の最後尾に移動
textRange.select();
}
}
// ---------------------------------------------------
// 挿入する文字列の入力用に jQuery UI の dialog を利用
$(function () {
$("#dialog").dialog({
bgiframe: true,
autoOpen: false,
modal: true,
resizable: false,
buttons: {
'Insert': function () {
insertText(
$('#textarea').get(0),
$('#textbox').val()
);
$(this).dialog('close');
},
'Cancel': function () {
$(this).dialog('close');
}
},
open: function () {
$('#textbox').val('')
}
});
$('#buttonShowDialog').click(function () {
if (document.selection != undefined) {
textRange = getTextRange($('#textarea').get(0));
}
$('#dialog').dialog('open');
});
});
//]]>
</script>
</head>
<body style="font-size: 12px;">
<h1>キャレット位置に文字列を挿入</h1>
<textarea id="textarea" cols="50" rows="5">textarea のキャレット位置に文字列を挿入します。</textarea><br />
<button id="buttonShowDialog">ダイアログ表示</button>
<div id="dialog" title="挿入する文字列">
<p>ここに入力:<br />
<input type="text" id="textbox" size="30" /></p>
</div>
</body>
</html>
textarea の文字列が選択されている場合、その文字列を dialog に入力した文字列で置き換えます。文字列を選択していない場合(キャレットのみの場合)、キャレットの位置に dialog に入力した文字列を挿入します。
IE9, Firefox 9.0.1, Safari 5.1.2, Opera 11.60 で検証して期待通りに動くことを確認しました。(その他のブラウザは検証してないです)