Make組ブログ

Python、Webアプリや製品・サービス開発についてhirokikyが書きます。

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で対応された履歴はこちらです。

chromestatus.com

Google ChromeSafariではできるので、そこまで困らないのが事実です(僕はFirefoxユーザーですが)。

document.execCommandは使わない

以前まではClipboard API経由でリッチテキストをコピーできませんでした。少し前の記事ですと document.execCommand('copy') とイベントリスナーを使って何とかする方法も書かれていますが、現在は避けたほうが良いかと思います。

document.execCommand 自体が非推奨になっていますので、できれば Clipboard を使いましょう。

developer.mozilla.org

まとめ

Clipboard APIを使ってリッチテキスト(書式付きテキスト)のコピーはできます! Firefoxは執筆時点で未対応ですが、そこは割り切れる範囲かなという気もします。

document.execCommand('copy') はなるべく使わないようにしましょう。

今後、対応されていくと良いなと思っています。

caniuse.com


執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました