JavaScriptのClipboard APIでリッチテキスト(書式付きテキスト)をコピーする
クリップボードにリッチテキストをコピーする方法を説明します。今回はとくにClipboard APIという現在推奨された方法で実装します。
「リッチテキストをコピー」というのは、ペーストしたときにWYSIWYGエディターへ書式が有効なまま入力されることを言っています。たとえばWordでコピーをすると、見出しや太字などを含めてコピーされるのと同じことです。
Clipboardを使ってリッチテキストをコピーする
標準のClipboard APIを使ってリッチテキストをコピーするには、以下のようにします。
const body = '<h1>見出し</h1><strong>太字</strong>' const blob = new Blob([body], { type: 'text/html' }) const blobPlain = new Blob([body], { type: 'text/plain' }) const item = [new window.ClipboardItem({ 'text/html': blob, 'text/plain': blobPlain })] await navigator.clipboard.write(item)
(たとえば「コピー」ボタンをクリックしたときなどに実行してください)
MIMEタイプに 'text/html' と指定して、Blobを渡すことでできます。こうすることでHTMLと認識させられるので、WordやWYSIWYGエディターへペーストしたときに書式が有効となります。Google Chromeの場合、コピーしたHTMLは自動でサニタイズされます。
実装するときは 'text/plain' としてもコピーしてください。そうしないと、メモ帳などにプレーンテキストとして貼り付けられるときに動作しません。
Firefoxは未対応
2022年1月26日時点ではFirefoxがHTMLのコピーに対応していません。
window.ClipboardItem が存在するかなどをチェックして、ない場合は navigator.clipboard.writeText を使ってプレーンテキストのみコピーするのが良いと思います(細かい実装の話はお任せしますが)。
Google Chromeで対応された履歴はこちらです。
text/html support for async clipboard api - Chrome Platform Statuschromestatus.com
Google ChromeとSafariではできるので、そこまで困らないのが事実です(僕はFirefoxユーザーですが)。
document.execCommandは使わない
以前まではClipboard API経由でリッチテキストをコピーできませんでした。少し前の記事ですと document.execCommand('copy') とイベントリスナーを使って何とかする方法も書かれていますが、現在は避けたほうが良いかと思います。
document.execCommand 自体が非推奨になっていますので、できれば Clipboard を使いましょう。
Document.execCommand() - Web APIs | MDNdeveloper.mozilla.org
まとめ
Clipboard APIを使ってリッチテキスト(書式付きテキスト)のコピーはできます! Firefoxは執筆時点で未対応ですが、そこは割り切れる範囲かなという気もします。
document.execCommand('copy') はなるべく使わないようにしましょう。
今後、対応されていくと良いなと思っています。
Clipboard API: write | Can I use... Support tables for HTML5, CSS3, etccaniuse.com
執筆:Kiyohara Hiroki (@hirokiky) (Shodoで執筆されました)