web-dev-qa-db-ja.com

javascriptをクリップボードにカット/コピー/貼り付け:Googleはそれをどのように解決しましたか?

はい、この質問は何度も尋ねられました。JavaScriptを使用してシステムのクリップボードとの間でコピーと貼り付けを行う方法は?これまでのところ、部分的な解決策とハックしか見つけていません。過去に頻繁に尋ねられたのは、まだ有効な解決策がないためです。しかし、Googleドキュメントには、キーボードイベントとボタンの両方に対して実際に機能するソリューションがあることがわかりました。だから、それは可能ですが、彼らはそれをどのように行うのですか? Software Saladの記事 JavaScriptを使用したシステムクリップボードへのアクセス–聖杯? は、問題の素晴らしい概要を提供します(しかし数年前です)。

要するに:

  • キーボードイベントctrl + x、ctrl + c、ctrl + vを使用して、準備されたデータを含む非表示のテキスト領域からテキストをコピーするか、非表示のフィールドに貼り付けられたテキストをキャッチして、それで何かを行うことができます

  • flashまたはJavaアプレットを介したハックを使用して、ユーザーの承認を必要とせずにシステムのクリップボードに何かをコピーできます。

  • IEの場合はclipboardData.setDataを使用し、他のブラウザの場合はexecCommandを使用して、実際のソリューションを使用できます。これは、ユーザーの承認に依存します。

Googleがクリップボードの問題にどのように取り組んだか、ご存知ですか?

23
Jos de Jong

[注:この回答は、書かれた時点では正確であり、OPの質問に正しく回答しました。しかし、テクノロジーはそれ以来進化してきました。 Webアプリでのコピーアンドペーストのサポートに興味がある場合は、このページの最新の回答をご覧ください。 —ruakh]


しかし、Googleドキュメントには、キーボードイベントとボタンの両方に対して実際に機能するソリューションがあることがわかりました。

いいえ、ありません。あんまり。キーボードイベントの場合、Googleドキュメントは何もしません。ブラウザのデフォルトのコピーアンドペースト機能をblockしません。そのため、ユーザーはGoogleドキュメントを邪魔することなく自由にコピーして貼り付けることができます。ボタンの場合、Googleドキュメントはsystemクリップボードをサポートしていませんが、完全にGoogleドキュメント内にある独自の「ウェブクリップボード」をサポートしています。ツールバーのボタンを使用して、コンピューター上の別のプログラムに貼り付けるテキストをコピーしたり、コンピューター上の別のプログラムからコピーしたテキストを貼り付けることはできません。

この詳細については、 "Googleドキュメントでのコピーと貼り付け" を参照してください。 (これは開発者向けではなくユーザー志向ですが、サポートされているものとサポートされていないものを明確にする適切な仕事をします。)

11
ruakh

私はその質問がずっと前に投稿されたことを知っていますが、Googleがどのようにそれを行うかを確認する必要があったので、誰かがそれが役に立つと思うかもしれません。

実際、グーグルはシステムのクリップボードも使用していますが、少し注意が必要です。キーボードショートカットを使用する場合は、コピー/貼り付け/カットイベントをキャッチできます。窓:

_window.addEventListener('copy', function (ev) {
    console.log('copy event');
    // you can set clipboard data here, e.g.
    ev.clipboardData.setData('text/plain', 'some text pushed to clipboard');
    // you need to prevent default behaviour here, otherwise browser will overwrite your content with currently selected 
    ev.preventDefault();
});
_

キーボードショートカットの実際の例: http://jsfiddle.net/tyk9U/

残念ながら、これはキーボードショートカットの唯一の解決策であり、ネイティブ(信頼できる)コピー/カット/貼り付けイベントがないとクリップボードデータにアクセスできないため、コンテキストメニューに問題があります。しかしグーグルは面白いトリックをします。 contenteditable要素のコマンドを実行できるAPI document.execCommand()があり、document.execCommand('copy')を介してトリガーできる 'copy'コマンドがあります。しかし、Chromeのコンソールでこれを試すと、falseが返されます。少し時間をかけて調べたところ、Chrome拡張機能がインストールされており、ドメイン「drive.google.com」と「docs.google.com」のクリップボードアクセスを可能にする「Googleドライブ」(chrome:// apps /にアクセスすると、そこに表示されます)と呼ばれます。ドキュメントまたはスプレッドシートを開きますコンソールにdocument.execCommand('copy')と入力します-trueが返されます。拡張機能をアンインストールすると、コンテキストメニューからクリップボード操作を使用できなくなります。

非常にシンプルなマニフェストファイルを使用して、このようなアプリケーションを自分で作成できます(詳細はこちら https://developer.chrome.com/apps/first_app ):

_{
    "manifest_version": 2,
    "name": "App name",
    "description": "App description",
    "version": "1.0",
    "app": {
        "urls": [
            "http://your.app.url.here/"
        ],
        "launch": {
            "web_url": "http://your.app.url.here/"
        }
    },
    "icons": {
        "128": "x-128.png"
    },
    "permissions": [
        "clipboardRead",
        "clipboardWrite"
    ]
}
_

ここの「許可」フィールドは、クリップボード操作を可能にします。

これを有効にすると、document.execCommand('copy')を実行できるようになり、機能します(trueが返されます)。しかし、これだけではありません-document.execCommand('copy') in chromeはコピーイベントをトリガーし、キーボードクリップボードのショートカットのキャッチに使用されるのと同じコードでキャッチできます。それ。

もちろん、この説明はChromeでのみ有効です。

27
Mateusz W

他のユーザーがこのスレッドに投稿したものに加えて、キーボードショートカットアプローチ(Mac OS XではCTRL + CまたはCMD + C)と、コピーアクションをトリガーするカスタムボタンアプローチを示す完全に機能する例を作成しました。

完全なデモはここにあります: http://jsfiddle.net/rve7d/

私はこのデモを作成しようとしているときにMateusz Wの回答が非常に有用であることがわかりましたが、彼はIEのサポートを考慮していません。

if(window.clipboardData) {
    // use just 'Text' or 'Url' as a first param otherwise strange exception is thrown
    window.clipboardData.setData('Text', 'Text that will be copied to CB');        
} else if(ev.originalEvent.clipboardData) {
    ev.originalEvent.clipboardData.setData('text/plain', 'Text that will be copied to CB');      
} else {
    alert('Clipboard Data are not supported in this browser. Sorry.');
}

PS:カスタムスプレッドシートビューコンポーネントにこの機能が必要で、途中でGoogleスプレッドシートのソースコードを分析したので、私のソリューションはほとんど彼らのソリューションに準拠しています。

4
Marek Suscak

グーグルは非常にシンプルですがクールな方法を使用しています。 firebugを使用すると、読み込まれたHTMLコードにサイズ1のテキスト領域があることがわかります。Googleドキュメントでは、ユーザーがテキストを選択してctrl + cを押すと、イベントをキャプチャし、いくつかの手法で取得します。 docコンテナで選択され、テキスト領域の値をそのコンテンツに設定するテキスト。それはフォーカスしてテキスト領域を選択するよりも。これで、ctrl + cイベントが解放されます。しかし、テキストがテキスト領域で選択されているため、イベントが発生すると、ブラウザーはテキスト領域にテキストをコピーし、コピーされたテキストを取得します。

3
coder hacker
<p>COPY : </p>
<p>Email me at <a class="js-emaillink" href="mailto:[email protected]">[email protected]</a></p>
<p><button class="js-emailcopybtn" value="clipboard" >clipboard</button></p>
<textarea rows="10" cols = "12"></textarea>
<p>CUT: </p>
<p><textarea class="js-cuttextarea">Hello I'm some text</textarea></p>
<p><button class="js-textareacutbtn" disable>Cut Textarea</button></p>
<script>
//copy clipboard
var copyEmailBtn = document.querySelector('.js-emailcopybtn');
copyEmailBtn.addEventListener('click', function(event) {
  // Выборка ссылки с электронной почтой
  var emailLink = document.querySelector('.js-emaillink');
  var range = document.createRange();
  range.selectNode(emailLink);
  window.getSelection().addRange(range);
  try {
    // Теперь, когда мы выбрали текст ссылки, выполним команду копирования
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copy email command was ' + msg);
  } catch(err) {
    console.log('Oops, unable to copy');
  }
  // Снятие выделения - ВНИМАНИЕ: вы должны использовать
  // removeRange(range) когда это возможно
  window.getSelection().removeAllRanges();
});
//cut
var cutTextareaBtn = document.querySelector('.js-textareacutbtn');
cutTextareaBtn.addEventListener('click', function(event) {
  var cutTextarea = document.querySelector('.js-cuttextarea');
  cutTextarea.select();
  try {
    var successful = document.execCommand('cut');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Cutting text command was ' + msg);
  } catch(err) {
    console.log('Oops, unable to cut');
  }
});
</script>
0
zloctb