はじめに
「URLをコピー」「コマンドをコピー」——こうしたボタンを自分で実装しようとすると、意外と面倒なことに気づきます。document.execCommand('copy') を使うには、まずコピーしたいテキストを一時的な <textarea> に入れて選択状態にする、という遠回りな手順が必要だからです。しかもクリップボード操作は昔からFlashに頼っていた時代もあり、ブラウザ間の差異に振り回されがちな領域でした。
Clipboard.jsは、この面倒な手順をHTMLの属性ひとつで解決してくれるライブラリです。「Modern copy to clipboard. No Flash. Just 3kb gzipped」というキャッチコピーどおり、Flash不要・軽量・シンプルという3拍子がそろっています。
とはいえ、読むより触った方が早いと思います。ボタンを押すだけでテキストがクリップボードにコピーされる様子を、先に見てみましょう。
Clipboard.jsとは
Clipboard.jsは、Zeno Rochaによって開発されたJavaScriptライブラリで、HTML要素に data-clipboard-* という属性を付けるだけで、クリックした際にテキストをクリップボードへコピー(またはカット)できるようにするものです。内部的にはブラウザのコピー機能を利用しており、Flashのようなプラグインは一切必要ありません。
主な特徴
- 超軽量 - gzip後で約3KBしかなく、ページの読み込み速度にほぼ影響を与えない
- 依存関係ゼロに近い設計 -
new ClipboardJS(selector)の1行で初期化でき、jQueryなどのフレームワークを必要としない - データ属性ベースのシンプルなAPI -
data-clipboard-textやdata-clipboard-targetを付けるだけで、コピー元・コピー内容を指定できる - success/errorイベントによる結果通知 - コピーの成否をイベントで受け取り、トースト表示などの独自フィードバックを実装できる
- 幅広いブラウザ対応 - Chrome 42+、Firefox 41+、Safari 10+、Edge、IE 9+までカバーしている
インストール
npmからインストールする場合は以下のコマンドを実行します。
npm install clipboard
CDN経由で読み込む場合は、<script> タグを1つ追加するだけで使い始められます。
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
ES modules環境であれば、以下のようにimportして使うこともできます。
import ClipboardJS from 'clipboard'
Clipboard.jsのサンプルを動かす
Clipboard.jsの中心的な使い方は、コピーの起点となる要素(多くはボタン)に data-clipboard-target でコピー元の要素を指定し、new ClipboardJS() でそれを監視することです。以下のサンプルでは、入力欄の値をボタンでコピーし、success イベントでその結果を画面に表示します。要点をまとめると次のようになります。
import ClipboardJS from 'clipboard'
// data-clipboard-targetで指定した要素の値(またはテキスト)をコピー対象にする
const clipboard = new ClipboardJS('.copy-btn')
clipboard.on('success', (e) => {
console.log('コピーされたテキスト:', e.text)
e.clearSelection() // コピー後に選択状態を解除する
})
clipboard.on('error', (e) => {
console.error('コピーに失敗しました', e.action)
})
実際に動かせるものが下です。入力欄の値を書き換えてからボタンを押すと、その内容がコピーされてメッセージが変わります。
入力欄のURLを別の文字列に書き換えてから「コピー」を押すと、e.text に書き換え後の値が渡ってくることが確認できるはずです。data-clipboard-target に指定するセレクタを別の要素(<textarea>や<pre>など)に変えても、同じ仕組みでコピーできます。
基本的な使い方
最もシンプルな使い方は、data-clipboard-text にコピーしたい文字列を直接書いてしまう方法です。コピー元の要素をDOMに用意する必要がなく、固定文言をコピーさせたいときに便利です。
<button class="btn" data-clipboard-text="Hello, Clipboard.js!">
コピー
</button>
import ClipboardJS from 'clipboard'
const clipboard = new ClipboardJS('.btn')
clipboard.on('success', (e) => {
console.log(e.action) // 'copy'
console.log(e.text) // 'Hello, Clipboard.js!'
})
new ClipboardJS() はCSSセレクタ文字列だけでなく、HTML要素そのものや要素の配列も受け付けます。ページ内に同じクラスのボタンが複数あっても、1回の初期化でまとめて対象にできます。
実践的なユースケース
固定テキストをコピーする
SNSシェア用の定型文や、サポートに問い合わせる際のエラーコードなど、内容が変わらないテキストをコピーさせたい場面では data-clipboard-text が最も手軽です。ボタンにテキストを埋め込むだけで、JavaScript側は成功・失敗の通知だけを担当します。
コマンドやコードスニペットをコピーする
READMEやドキュメントサイトでよく見る「コマンド横のコピーアイコン」も、Clipboard.jsが得意とするパターンです。data-clipboard-target でコピーボタンとは別の要素(<code>や<pre>)を指定すれば、表示用のテキストとコピー対象を分離できます。
入力内容をカットする
data-clipboard-action="cut" を指定すると、コピーではなくカット(コピー後に元の値を空にする)として動作します。入力フォームの「切り取り」ボタンなど、コピー後に入力欄をクリアしたい場面で使えます。対象にできるのは <input> や <textarea> のような値を持つ要素です。
「カット」を押すと、テキストエリアの中身がクリップボードにコピーされたうえで空になることが確認できます。data-clipboard-action を外す(または "copy" にする)と、値は残ったままコピーだけが行われる通常の挙動に戻ります。
動的な値をコピーする
招待コードや現在時刻など、クリックのたびに変わる値をコピーさせたい場合は、text オプションに関数を渡します。data-clipboard-text が固定文字列しか扱えないのに対し、こちらはトリガー要素(trigger)を受け取って毎回好きな値を返せます。
ボタンを押すたびに、コピーされる時刻の文字列が変わることが分かります。text と同様に target や action オプションにも関数を渡せるため、クリックされたボタンの位置や状態に応じてコピー内容を切り替えるような、より複雑な実装にも対応できます。
まとめ
Clipboard.jsは、data-clipboard-* 属性と new ClipboardJS() の組み合わせだけで、コピーボタンをFlashなしに実装できる軽量なライブラリです。固定テキストのコピーからフォーム値の取得、カット操作、動的な値の生成まで、data-clipboard-text / data-clipboard-target / data-clipboard-action / text オプションを使い分けることで幅広いユースケースに対応できます。
success / error イベントを使えば、コピー結果に応じたフィードバックUIも自由に組めます。まずは既存のボタンに data-clipboard-text を1つ追加するところから、Clipboard.jsを試してみてはいかがでしょうか。
