JavaScriptでクリップボードにテキストをコピーする

こんにちは、ナカムラです。
今回はJavaScriptを使って、特定のテキストをクリップボードへコピーする処理を書いていこうと思います。

クリップボードとは

クリップボードとは、テキストや画像などを一時的に保存している場所です。
テキストを選択してcommand+Cや、右クリックしてコピーした時に使われています。

日常的によく使っていると思いますが、Webサイトではどういう時に必要になるでしょうか。
ユーザーがコピーをしたくなるものといえば、
キャンペーンでよくある「ハッシュタグ」ではないかと思います。
指定の文字列を使って投稿を促しますが、キャンペーンの用のタグは長かったりします。
SNSで投稿するときに自分で打つのは面倒ですよね。
応募する気も失せてしまいます。

そしてこういうキャンペーンは、制作期間がとても短いことが多く、残念ながらテキスト情報の部分も画像で書き出してしまうこともよくあります。
画像にしてしまうことで、テキストを選択してコピーができない状態になります。
このままではよろしくないので、JavaScriptでコピーできるようにしたいと思います。

DEMO

See the Pen Untitled by Nakamura (@takayo-nakamura) on CodePen.

※埋め込みのウィジェットの表示ではうまく機能しなかったので、下記のリンク先でご確認ください。 https://codepen.io/takayo-nakamura/pen/qBoaVza

inputタグのvalue値にコピーさせたい文字列を記入します。
ボタンをクリックした時にinputタグのvalue値を取得し、
クリップボードにコピーし、コピーしたことをお知らせします。
では処理ごとに見ていきましょう。

クリップボードへコピー(ボタンをクリックした時)

// クリップボードへコピー(ボタンをクリックした時)
copyButton.addEventListener('click', () => {
  const tagValue = tagText.value // inputタグのvalue値を変数へ挿入する
  copyToClipboard(tagValue) // 関数copyToClipboardを実行する
})

必要な要素は取得した後の記述になります。
ボタンをクリックした時にinputタグのvalue値を変数へ挿入し、
関数copyToClipboardを実行します。
この時、引数にtagValueを入れて渡します。

クリップボードへコピー(コピーの処理)

// クリップボードへコピー(コピーの処理)
function copyToClipboard (tagValue) {
  if (navigator.clipboard) { // navigator.clipboardが使えるか判定する
    return navigator.clipboard.writeText(tagValue).then(function () { // クリップボードへ書きむ
      messageActive() //メッセージを表示する
    })
  } else {
    tagText.select() // inputタグを選択する
    document.execCommand('copy') // クリップボードにコピーする
    messageActive() //メッセージを表示する
  }
}

関数copyToClipboardの説明になります。
クリップボードへのコピーにはnavigator.clipboardを使用しますが、
使用できない環境もあるため、まずはnavigator.clipboardが存在するかを判定します。

navigator.clipboardについてはこちら
Navigator.clipboard - Web API | MDN

クリップボードへの書き込みはこちらの記述になります。

return navigator.clipboard.writeText(tagValue)

書き込み後、messageActive()を実行してメッセージを表示します。

次に、navigator.clipboardが使えなかった場合の処理です。

    tagText.select() // inputタグを選択する
    document.execCommand('copy') // クリップボードにコピーする

先ほどと違うのは、コピーの処理の部分です。
navigator.clipboardの代わりに、document.execCommand('copy')を使っています。

Document.execCommand() - Web API | MDN

メッセージを表示

// メッセージを表示
function messageActive () {
  message.classList.add('is-active') // メッセージを表示する
  setTimeout(() => { // メッセージを非表示にする
    message.classList.remove('is-active')
  }, 1600)
}

メッセージの要素をis-activeというクラスの付け替えによって表示しています。
ずっと出ていると邪魔になるので、setTimeoutで一定時間経ったら消えるようにしています。

最後に

document.execCommand('copy')は非推奨になったやり方なので、
navigator.clipboardが使えなかった場合の対応として使用しています。
今後使えなくなる可能性がありますので、注意が必要です。
※現状、iOSでも使えるはずのnavigator.clipboardが使えない状況なので、この手法も使わざるをえないのですが、どうなるんでしょう…
今のところ使える手法ということだけご留意ください。
クリップボードへのコピーではなく、テキストをコピーしやすいようにポップアップ表示する仕様にとどめても良いかもしれません。

(2022/12/15 追記)iOSはクリップボードにアクセスする処理をしてからコピーする方法があるらしいのですが、把握できていないのでまたそのうち調べてみたいと思います・・・