クリップボードへのアクセス


ユーザーのクリップボードにアクセスすることは、長い間、する最もよいことでありませんでした.私たちは document.execCommand APIをコピーして貼り付け、ユーザーのクリップボードからテキストを貼り付けます.
// #1. Use an input element
const input = document.querySelector('input');

// #2. Set the input's value to the text we want to copy to clipboard
input.value = 'hello there!';

// #3. Highlight the input's value
input.select();

// #4. Copy the highlighted text
document.execCommand('copy');
The input 要素を動的に作成したり、プロセス中に削除したり、スタイルをユーザーに表示されません.私は以前にこのアプローチを使用していた時代の間に、私は常に醜いと非常にエレガントではないと思った.幸いなことに、新しいWeb APIここでは、これははるかに簡単にすることです!

クリップボードAPI


The Async Clipboard API 提供するWebアプリは、プログラムを読み込んでから簡単にシステムクリップボードに書き込む機能を提供します.APIに関するいくつかの注意
  • でアクセスできますnavigator.clipboard
  • サイトはHTTPSまたはlocalhostを介して提供する必要があります
  • ページがアクティブなブラウザタブの場合のみ機能します
  • それでは、それが実際にどのように単純かを見てみましょう.

    クリップボードへの書き込み


    async function writeToClipboard(text) {
        try {
            await navigator.clipboard.writeText(text);
        } catch (error) {
            console.error(error);
        }
    }
    
    このメソッドはPromise , 私たちは、Aを連鎖させることによって解決するのを待つことができます.then() または使用async/await . その単一の、短い行のコードで、我々はちょうどクリップボードに我々のテキストを書きました!

    Note: In Firefox, the text gets written to the clipboard only when calling writeText() in response to a user gesture, otherwise it throws an exception.Chrome writes the text to the clipboard regardless of the user gesture. Both allows writing to the clipboard without having to request for permission.


    クリップボードからの読み取り


    async function readFromClipboard() {
        try {
            const text = await navigator.clipboard.readText();
            console.log(text);
        } catch (error) {
            console.error(error);
        }
    }
    
    このメソッドはPromise , とクリップボードに書き込むように簡単です.サイトが最初にクリップボードの内容を読み込もうとすると、ブラウザは要求されていないかどうかをユーザに問い合わせる.

    Note: In Chrome, permission to read the clipboard is automatically denied when the user has dismissed it several times (~3 times from my observation).

    Note: At the time of writing, Firefox (version 68) doesn't support the readText() method yet, with the MDN docs stating that it is only supported in browser extensions.


    クリップボードアクセス許可のチェック


    我々は、クリップボードにアクセスする許可を持っているかどうかを確認することができますPermissions API :
    await navigator.permissions.query({name: 'clipboard-read'});
    // or 'clipboard-write' for permission to write
    
    // sample result: {state: 'granted'}
    
    この結果を使用すると、クリップボードにアクセスできるかどうかをユーザーに知らせるUIを表示できます.

    クリップボードイベント


    私たちが簡単にクリップボードからの書き込みと読み取りを許可することから、theasyncクリップボードAPIもクリップボードのイベントを与えます.我々は、ユーザーがクリップボードに関連するアクションを実行するときに、コピー、カット、または貼り付けを聞くことによってcopy , cut , and paste それぞれのイベント.
    document.addEventListener('copy', event => {});
    document.addEventListener('cut', event => {});
    document.addEventListener('paste', event => {});
    
    これらのイベントは、非同期クリップボードAPIを使用してクリップボードにアクセスするときには起動しませんwriteText() or readText() ), しかし、彼らは対応する呼び出しdocument.execCommand コマンド.呼び出しevent.preventDefault() アクションをキャンセルし、クリップボードの現在の状態を維持します.
    これらのイベントは、アクションがページ上で実行されたときにのみ、他のページやアプリケーションで実行されないときに発生します.
    クリップボードevent オブジェクトはclipboardData aであるプロパティDataTransfer オブジェクト.これにより、クリップボードに書き込まれるデータを上書きすることができ、他の形式でデータを書き込む機会を与えられますtext/html :
    document.addEventListener('copy', event => {
        event.preventDefault();
        event.clipboardData.setData('text/plain', 'COPY ME!!!');
        event.clipboardData.setData('text/html', '<p>COPY ME!!!</p>');
    });
    
    これをするとき、我々は電話する必要がありますevent.preventDefault() 我々のカスタムデータは、元の代わりにクリップボードに書き込まれます.For cut and paste イベントは、ドキュメント内のコンテンツの削除/挿入を処理する必要があります.

    イメージサポート


    これまでのところ、我々は、読み取り/書き込みテキストをサポートするAsyncのクリップボードAPIのバージョンを見てきただけで、すでにクールに見える!APIへの最近の追加は、プログラムの読み込みを簡単にクリップボードに画像を書くこと、画像のサポートです!

    Note: For the meantime, only PNG images are supported, but support for other image formats (and maybe files in general) will be added in the future.


    クリップボードに画像を書き込む


    クリップボードに画像を書く前に、まずAを得る必要がありますBlob 画像のイメージBLOBを得る方法はいくつかあります.
  • ユーザーにファイル入力を使用してイメージを選択するよう依頼する
  • fetch() BLOBとしてのネットワークからのイメージresponse.blob() )
  • 画像をAに描画するcanvas 呼び出しcanvas.toBlob()
  • 一旦イメージblobを持っているならばimageBlob ), のインスタンスを作成する必要がありますClipboardItem 我々のイメージBlobを含むこと:
    new ClipboardItem({ 'image/png': imageBlob})
    
    The ClipboardItem コンストラクタは、キーがMIME型で、値が実際の塊自身であるオブジェクトを受け入れます.私たちは異なるタイプを使用しているデータの異なる表現を与えて、複数のMIMEタイプとBLOB組を提供することができます.
    今、我々はクリップボードに我々のイメージを書くことができますnavigator.clipboard.write() :
    async function writeToClipboard(imageBlob) {
        try {
            await navigator.clipboard.write([
                new ClipboardItem({
                    'image/png': imageBlob
                })
            ]);
        } catch (error) {
            console.error(error);
        }
    }
    
    navigator.clipboard.write() 配列を受け入れるClipboardItem ただし、書き込み時には単一の項目のみをサポートしています.これはたぶん彼の未来を変えるでしょう.

    クリップボードから画像を読み込む


    クリップボードからの読み取り項目(テキストだけでなく)を使用することができますnavigator.clipboard.read() :
    async function readFromClipboard() {
        try {
            const items = await navigator.clipboard.read();
        } catch (error) {
            console.error(error);
        }
    }
    
    It returns an array of ClipboardItem 現在のところ、システムクリップボードの内容を反映していますが、Chromeではクリップボードの最新の項目だけを返します.
    この配列をループすることで、各項目を取得できます.すべての利用可能なMIMEタイプをClipboardItem を介してitems プロパティと、その非同期を使用して、特定の型の実際のBLOBデータを取得しますgetType() メソッド:
    for (let item of items) {
        console.log(item.types); // e.g. ['image/png']
    
        for (let type of item.types) {
            const blob = await item.getType(type);
        }
    }
    
    我々がBlobを得たあと、我々は現在我々がそれと望む何でもすることができます.私たちはFileReader API BLOBを必要なフォーマットに変換するには、次の手順に従います.
    const reader = new FileReader();
    reader.onload = () => {
        const data = reader.result;
        // e.g. 'data:image/png;base64,...'
    };
    
    reader.readAsDataURL(blob);
    
    非同期クリップボードAPIwrite() and read() メソッドは、クリップボードにアクセスするための一般的な方法を提供します.実際にはwriteText() and readText() 以前に議論されたメソッドはちょうどそれらのための便利なメソッドで、そうでなければ使用することができますwrite()/read() 活字を使ってtext/plain .
    async function writeToClipboard(text) {
        try {
            await navigator.clipboard.write([
                new ClipboardItem({
                    'text/plain': new Blob([text], {type: 'text/plain'})
                })
            ]);
        } catch (error) {
            console.error(error);
        }
    }
    
    async function readFromClipboard() {
        try {
            const items = await navigator.clipboard.read();
            for (let item of items) {
                const data = item.getType('text/plain');
                // convert `data` to string using FileReader API's
                // `.readAsText(data)` method
            }
        } catch (error) {
            console.error(error);
        }
    }
    

    ブラウザーサポートと特徴発見


    テキストをサポートしているAsyncのクリップボードAPIreadText() まだWebアプリケーションのために利用できません.PNG画像のサポートについては、Chromeのみが書き込み時にそれをサポートし、Chrop 76で出荷します.参照browser compatibility table を参照してください.
    我々はすでに機能を介してサポートされているブラウザでは、このAPIを活用することができますnavigator.clipboard が存在する.
    if (navigator.clipboard) {
        // Safe to use Async Clipboard API!
    } else {
        // Use document.execCommand() instead
    }
    

    資源


    この記事を読んでくれてありがとう、あなたはそれを楽しんで、それから何かを学びました.ここでは、asyncクリップボードAPIについてもっと知りたい方があります.
  • Clipboard API and events, W3C Working Draft
  • Clipboard API on MDN
  • Unblocking Clipboard Access
  • Image Support for the Async Clipboard API