ボタンなどをクリックしてテキストをクリップボードにコピーすることは、
InternetExplorerであれば、JavaScriptを使って比較的容易に実現できます。

ソース(IE限定)

<input type="submit" onClick="javascript:clipboardData.setData('Text', this.value);" value="このテキストをコピーする" />

サンプル




しかし、この「clipboardData.setData」という関数はIE独自のもので、
IE以外のブラウザでは実装されていません。
というわけで、FirefoxなどIE以外のブラウザでクリップボードを使うには、他の方法が必要です。

この解決には以前から、Flashを利用した手法が使われてきたのですが、
Flashがver10になって以降セキュリティが強化され、多くが動かなくなってしまいました。
というわけで、今現在有効な手段についてサンプルを交えつつ。
IE以外のブラウザでコピーを実現するにはこちらのライブラリを使用すると簡単です。

zeroclipboard - Google Code

ページの右メニューのFeatured Downloadsから最新のものをダウンロードしておきます。


インストール

ダウンロードしたファイルを解凍すると、以下のファイルが出てきます。



ソースも含まれているのでたくさんありますが必要なのは次の2つだけです。

  • ZeroClipboard.js
  • ZeroClipboard.swf

それぞれ適当な場所に配置します。

今回は、下記のように配置しています。

┣ js
┃ ┗ ZeroClipboard.js
┗swf
  ┗ ZeroClipboard.swf


次に、ZeroClipboard.jsを開いてZeroClipboard.swfの場所を設定します(8行目)。

moviePath: '/swf/ZeroClipboard.swf', // URL to movie

以上で、準備は完了です。



では実際に使ってみます。


単体のボタンのテキストをコピーする場合

ドキュメントを読んでみると、ボタンの後に数行記述すれば実現できるようです。

Instructions - zeroclipboard - Google Code

一番簡単に書いてみると、こうなります。

<input type="submit" id="clipButton_1" value="このテキストをコピーする" />
<script type="text/javascript">
// ボタン
  var btn = document.getElementById('clipButton_1')
// インスタンス
  var clip = new ZeroClipboard.Client();
// マウスオン時のカーソルの設定
  clip.setHandCursor(true);
  clip.setText(btn.value);
  clip.glue(btn);
</script>

サンプル1(ボタン単体でコピー)


<head>タグ内に記述したい場合は、例えばこんな感じとか。
(prototype.js使用の場合)

サンプル2(ボタン単体でコピー改)



テキストエリアの内容をコピーする場合

ブログパーツの配布の時などによくあるパターンです。
こんな感じです。

<textarea id="clipTarget_3">このエリアのテキストをコピーする</textarea>
<input type="submit" id="clipButton_3" value="コピー" />
<script type="text/javascript">
// テキストエリア
  var target = document.getElementById('clipTarget_3')
// ボタン
  var btn = document.getElementById('clipButton_3')
// インスタンス
  var clip = new ZeroClipboard.Client();
// マウスオン時のカーソルの設定
  clip.setHandCursor(true);
  clip.setText(target.value);
// 2回目以降に備える
  if (clip.div) {
    clip.receiveEvent('mouseout', null);
    clip.reposition(btn);
  } else {
    clip.glue(btn);
  }
</script>

サンプル3(テキストエリアの中身をコピー)


ただこれだと、せっかくテキストエリアなのに入力に対応できません。
自由に入力したテキストをコピーするには、textareaにonChangeを設定します。

<textarea id="clipTarget_4" onChange="clip.setText(this.value)">このエリアのテキストをコピーする</textarea>
<input type="submit" id="clipButton_4" value="コピー" />
<script type="text/javascript">
// テキストエリア
  var target = document.getElementById('clipTarget_4')
// ボタン
  var btn = document.getElementById('clipButton_4')
// インスタンス
  var clip = new ZeroClipboard.Client();
// マウスオン時のカーソルの設定
  clip.setHandCursor(true);
  clip.setText(target.value);
// 2回目以降に備える
  if (clip.div) {
    clip.receiveEvent('mouseout', null);
    clip.reposition(btn);
  } else {
    clip.glue(btn);
  }
</script>

サンプル4(テキストエリアの中身をコピー・改)


<head>タグ内に記述したい場合は、例えばこんな感じとか。
(prototype.js使用の場合)

サンプル5(テキストエリアの中身をコピー・改2)



複数のボタンに対応する

ここまでの例は複数のボタンを設置するときには、
それぞれidを変えてやる必要がありました。

しかし、それをいちいちやるのは結構めんどい。

というわけで、idを使わずにやってみます。
prototype.jsのgetElementByClassNameは遅いと評判なので止めて、
こんな感じでどうでしょうか。

Event.observe(window, "load", function() {
// インスタンス
  var clip = new ZeroClipboard.Client();
  clip.setHandCursor(true);
// タグを取得
  var elements = document.getElementsByTagName('span');
  for(i=0; i<elements.length; i++) {
    if(elements[i].getAttribute('rel') == 'clipButton') {
      var btn = elements[i];
      Event.observe(btn, "mouseover", function() {
        this[1].setText(this[0].innerHTML);
        if (this[1].div) {
          this[1].receiveEvent('mouseout', null);
          this[1].reposition(this[0]);
        } else {
          this[1].glue(this[0]);
        }
      }.bind([btn, clip]));
    }
  }
});

サンプル6(複数のボタンの中身をそれぞれコピー)

微妙に怪しいところ満載ですが、何とか動いてるかなと思います。
(submitボタンだとIEでなぜか判定領域の高さが幅と同じに…)



ごく簡単な例だけ挙げてみましたが、他にも使い方次第で色々やれるかと思います。
お試しくださいませー



追記:2009/03/05 11:08

  • 文中に置いたサンプルが一部動いていなかったので別ページにしました。
  • 文中一部動作に誤りがあったので修正しました。