https://idea-hack.com/blog/83232/
Clipboard jsをカスタマイズしてコピーボタンを実装する方法と4つのサンプルコード

Clipboard jsをカスタマイズしてコピーボタンを実装する方法と4つのサンプルコード

アプリケーションでユーザーにデータのコピーを催したい時に便利なClipboard jsの使い方とサンプルコードを紹介します。

データをコピーする方法はITに少しでも詳しい人であれば誰でも知っているはずです。Ctrl/Cmd+Aで選択してCtrl/Cmd+Cでコピーして、Ctrl/Cmd+Vで貼り付けるだけです。

しかし、ユーザーの中にはこのコピーの仕方やショートカットキーの使い方を知らない人もいます。

そんな時に必ずユーザーにデータをコピーしてもらう必要があったらどうでしょうか。

コピーボタンがないとユーザーはコピーする方法に四苦八苦してしまいます。

そこで、ユーザビリティを意識して、 Clipboard.jsでコピーボタンを実装する方法を紹介します。

KAZUKI

ライブラリを使わないで実装する方法もありますが、ブラウザごとに動作が異なり、セキュリティも意識しなければならなくなるので、ライブラリに頼った方が良いです。

Clipboard.jsとは

今回実装するサンプルコードは以下の前提で作ります。

  • コピーされるformフィールドを指定して、そこの値だけコピーさせる。(1つのページで異なる場所にあるデータをコピーさせたい場合は、その数分コピーボタンが必要になる。)

Clipboard.jsのインストール

ファイルのダウンロードと読み込み

NPMパッケージをインストールしたい人はGithubからGitコマンドで任意のフォルダ にダウンロードしてください。

もちろんZIPでも問題ないですし、後述しますがCDNも提供されていますので、CDN使う人は飛ばして構いません。

git
npm install zenorocha/clipboard.js

Gitコマンドに詳しくない人は下記記事も参考にどうぞ。

必要なファイルの読み込み

ダウンロードファイルの中には開発環境向けのファイルも入っているので必要なファイルだけ読み込みます。

  • clipboard.min.js

CDNを読み込みたい方は下記コードをコピーしてください。

HTML
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>

Clipboard.jsの使い方

それでは作成していきます。今回はフォームを用意して簡単なコピーボタンを用意します。

HTMLは下記の通りです。

HTML
<input type="text" id="website" value="https://idea-hack.com/" />
<button class="sample" data-clipboard-target="#website">copy</button>

このHTMLが「data-clipboard-target」を持っている点に注目してください。この属性で指定したID属性がコピーの対象になります。

JavaScriptは下記の通りです。

JavaScript
new ClipboardJS('.sample');

clipboard.jsでは、上記のJSでインスタンスを作成すると、そのクラスがついた要素を探し出します。

そして、「data-clipboard-target」属性がついている場合にclickイベントハンドラーを追加し、クリックされた時にdocument.exeCommnad('copy')を実行して、対象となる要素をコピーします。

もし失敗したら、コピー対象の要素を選択状態にします。

サンプルコード 1

ここまでの知識を踏まえると、下記のサンプルコードを理解いただけると思います。

Output
HTML
<input type="text" id="website_1" value="https://idea-hack.com/" />
<button class="sample_1" data-clipboard-target="#website_1">copy</button>
JavaScript
new ClipboardJS('.sample_1');

サンプルコード 2

下記のデモコードの様に「data-clipboard-target」の代わりに「data-clipboard-text」を付与することで、コピー対象を「data-clipboard-text」に指定されているテキスト要素をコピー支えることができます。

もちろん、この時はinput要素は必要ありません。

Output
HTML
<button class="sample_2" data-clipboard-text="This text will be copied">copy</button>
JavaScript
new ClipboardJS('.sample_2');

サンプルコード 3

コピーするだけでなく、カットすることも可能です。

実現するには「data-clipboard-action」を使用します。

Output
HTML
<input type="text" id="website_3" value="https://idea-hack.com/" />
<button class="sample_3" data-clipboard-target="#website_3" data-clipboard-action="cut">copy</button>
JavaScript
new ClipboardJS('.sample_3');
KAZUKI

ただし、Cutが使えるのがinputタグとtextareaタグに対してのみです。

「Copied」ボタンも表示したい

このままだと、コピーした時に「Copied」みたいなテキストが表示されないので、実際にコピーが成功されたかどうかがユーザーにはわかりません。

実装されない理由を作成者は下記の様に述べています。

Each application has different design needs, that’s why clipboard.js does not include any CSS or built-in tooltip solution.

 Zeno Rocha 

要するに「デザインはAPPによって変わるから、あえて付けていない」ということです。

そのため、自分たちで実装する必要があります。

サンプルコード 4

Output
HTML
<input type="text" id="website_4" value="https://idea-hack.com/" />
<button class="sample_4" data-clipboard-target="#website_4">copy</button>
CSS
.sample_4 {
  cursor: pointer;
  position: relative;
}

/* Tooltip */
.tooltip_copied::after {
  content: 'Copied!';
  background: #555;
  display: inline-block;
  color: #fff;
  border-radius: .4rem;
  position: absolute;
  left: 50%;
  bottom: -.8rem;
  -webkit-transform: translate(-50%, 0);
          transform: translate(-50%, 0);
  font-size: .75rem;
  padding: 4px 10px 6px 10px;
  -webkit-animation: fade-tooltip .5s 1s 1 forwards;
          animation: fade-tooltip .5s 1s 1 forwards;
}

/* Animation */
@-webkit-keyframes fade-tooltip {
  to {
    opacity: 0;
  }
}
@keyframes fade-tooltip {
  to {
    opacity: 0;
  }
}
JavaScript
const clipboard = new ClipboardJS('.sample_4');

// Select all .sample_4 items
const copyButtons = document.querySelectorAll('.sample_4');

// Remove .tooptip class by mouseout
for(let i=0;i<copyButtons.length;i++){
    copyButtons[i].addEventListener('mouseleave',clearTooltip);
}

function clearTooltip(e){
    e.currentTarget.setAttribute('class','sample_4');
}

// Add .tooltip class when it's clicked
function showTooltip(elem){
    elem.setAttribute('class','sample_4 tooltip_copied');
}

clipboard.on('success', function(e) {
    showTooltip(e.trigger);
});

document.querySelectorAll('.sample_4'); で sample_4 というクラスを取得します。

関数で elem.setAttribute('class','sample_4 tooltip_copied'); と記述して、クリックしたら tooltip_copied というクラスを加えます。

addEventListener('mouseleave',clearTooltip); の部分でカーソルが要素から離れた際にtooltip_copiedを取り除く処理を追加し、表示状態を元に戻します。

その上、tooltip_copied クラスの要素にCSSデザインを当てています。

まとめ

clipboardコピーの機能は実装する機会があまりないので、戸惑ってしまいがちですが、コード自体はとても簡単です。