WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

textarea のキャレット位置に文字列を挿入

by WebSurfer 9. January 2012 23:04

JavaScript を使って textarea のキャレット(カーソル)位置に文字列を挿入するサンプルです。

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 で検証して期待通りに動くことを確認しました。(その他のブラウザは検証してないです)

Tags: ,

JavaScript

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  June 2019  >>
MoTuWeThFrSaSu
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

View posts in large calendar