javascriptでクリップボードに文章をコピーする
今回はjavascriptでクリップボードに文章をコピーする方法を記載します。
いくつか方法を試しましたが、今回ご紹介する方法が最善かと思います。
textareaを作成してコピー??
今回ご紹介する方法以外に、 コピーしたいテキストを取り出して、createElementで作成したtextareaにその文章を入れ込み、選択させた状態にしてからコピーするというものがありました。
この方法でも動きましたが、iosのsafari??などで分岐が必要になったり、iosでコピーできない状況があったりしたので別の方法を探しました。
htmlの作成
まずはコピーしたい箇所のhtmlです
<p id="target">コピーしたい文章です!!</p>
javascriptの実装
今回ご紹介する方法は以下の通りです。
詳細解説は後述。
const ele = document.querySelector('#target'); const selected = window.getSelection(); const range = document.createRange(); range.selectNodeContents(ele); selected.removeAllRanges(); selection.addRange(range); const isSuccess = document.execCommand('copy'); selected.removeAllRanges();
解説
上記の実装を解説して行きます
要素の取得
// 対象の要素を取得 const ele = document.querySelector('#target');
selectionオブジェクトを取得
selectionオブジェクトを取得します。取得した選択文字列に対して処理を行うために必要です。
developer.mozilla.org
前述したtextareaやinputなどを使う方法でであれば、select()すればいいですが、今回のようにpタグなどを利用しており、select()が使えない場合にはSelectionが必要になります。
// seletionオブジェクト取得 const selection = window.getSelection();
このSelectionにコピー対象を渡してあげるという実装が必要になりますが、SelectionにはRangeオブジェクトしか渡すことができません。
なのでRangeオブジェクトを作成します。
Rangeオブジェクトの作成
Rangeオブジェクトを作成します。
rangeとは翻訳そのままですが、「範囲」を表すものです。
developer.mozilla.org
// rangeオブジェクトの作成 const range = document.createRange();
Rangeオブジェクトの範囲決定
指定した要素の内側を範囲とするための記述です。
今回であればidが「target」のpタグの内側が対象になります。
// Rangeオブジェクトの範囲決定 range.selectNodeContents(ele);
SelectionオブジェクトからRangeオブジェクトを削除
Selectionオブジェクトが別のRangeオブジェクトを有していることを考慮して削除しておきます。
// SelectionオブジェクトからRangeオブジェクトを削除 selection.removeAllRanges();
SelectionオブジェクトにRangeオブジェクトを追加
先ほど作成したRangeオブジェクトをSelectionオブジェクトに追加します。
// RangeオブジェクトをSelectionオブジェクトに追加 selection.addRange(range);
クリップボードにコピー
クリップボードへのコピーを実施します。
成功すればtrue、失敗すればfalseが返るのでそれによって挙動を変えましょう。
// クリップボードにコピー const isSuccess = document.execCommand('copy');
再度SelectionオブジェクトからRangeオブジェクトを削除
初期化の意味を込めてRangeオブジェクトを削除します。
// Rangeオブジェクトを削除 selection.removeAllRanges();
最後にハマったことを書いて終わりにします。
preタグからコピーするとGmailに正しく貼り付けができない
最初に実装した時にpreタグを使用していました。
<pre id="target">コピーしたい文章です!!</pre>
この値をコピーしてからGmailに貼り付けようとしても、空白状態となってしまいました。
pタグやdivタグにしたら問題なく動きました。
ちなみにGmail以外のiPhoneメールアプリ、Yahooメールなどは問題ありませんでした。
ご注意ください。
以上。