web-dev-qa-db-ja.com

document.execCommand( "paste")がGoogle Chromeで機能しないのはなぜですか?

拡張機能に問題があります。クリップボードからデータを貼り付けたい。

これまでのところ、私はこれを持っています:

function pasteAndGo()
{
    document.execCommand('paste')
    alert("Pasted")
}

アラートが表示されますが、何も貼り付けられていません。

変更が必要なのはdocumentの部分だと感じましたが、どうしたらよいかわかりません。何か案は?

14
Joseph Duffy

Chromeには実験的なクリップボードAPIがありましたが、これはChrome 13で削除されました。

Chromeは、より標準的なdocument.execCommand('paste')document.execCommand('copy')、およびdocument.execCommand('cut')コマンドに移行しました: https://developer.mozilla.org/en/Rich- Text_Editing_in_Mozilla#Executing%5FCommands

Chromeでは、マニフェストに権限を追加する必要があります: "clipboardRead"と "clipboardWrite"。 http://developer.chrome.com/extensions/declare_permissions。 html

Chrome 38までは、これらのクリップボードのアクセス許可は、バックグラウンドスクリプトなどの拡張ページでのみ使用可能でした。Chrome 39以降、コンテンツスクリプトもこれらのクリップボードAPIを使用できます。マニフェストファイルでクリップボードのアクセス許可を宣言した後( crbug.com/395376 )。

11
Boris Smus

これは、バックグラウンドページでうまく機能します。

function getClipboard() {
    var pasteTarget = document.createElement("div");
    pasteTarget.contentEditable = true;
    var actElem = document.activeElement.appendChild(pasteTarget).parentNode;
    pasteTarget.focus();
    document.execCommand("Paste", null, null);
    var paste = pasteTarget.innerText;
    actElem.removeChild(pasteTarget);
    return paste;
};

もちろん、拡張機能には「clipboardRead」権限が必要であり、メッセージパッシングを使用してこの情報をコンテンツスクリプトに戻す必要があります。

content.js:

chrome.extension.sendMessage({
    cmd: "clipboard", //$NON-NLS-0$
    action: "paste" //$NON-NLS-0$
}, function(response) {
    if (response.paste) {
        var range = document.getSelection().getRangeAt(0);
        range.deleteContents();
        range.insertNode(document.createTextNode(response.paste));
    }
});

background.js:

function getClipboard() {
    var pasteTarget = document.createElement("div");
    pasteTarget.contentEditable = true;
    var actElem = document.activeElement.appendChild(pasteTarget).parentNode;
    pasteTarget.focus();
    document.execCommand("Paste", null, null);
    var paste = pasteTarget.innerText;
    actElem.removeChild(pasteTarget);
    return paste;
};

function onClipboardMessage(request, sender, sendResponse) {
    if (request.action === "paste") { //$NON-NLS-0$
        sendResponse({
            paste: getClipboard()
        });
    }
}

chrome.extension.onMessage.addListener(onClipboardMessage);
6
stackunderflow

document.execCommand("paste")の呼び出しは、スクリプトがクリップボードから機密データ(パスワードなど)を読み取る可能性があるため、セキュリティ上の懸念があるため、「合理的な」ブラウザではサポートされていません。

これは、クリップボードイベントに関するdocument.execCommand("...")互換性マトリックスです。

        | "copy" | "paste" | "cut"
--------+--------+---------+--------
IE      |   OK   |   OK    |  n/a
--------+--------+---------+--------
Edge    |   OK   |   n/a   |  OK
--------+--------+---------+--------
Firefox |   OK   |   n/a   |  OK
--------+--------+---------+--------
Chrome  |   OK   |   n/a   |  OK

これに対する私の2セント:

  • EdgeFirefox、およびChromeの動作は、「合理的」です。クリップボードからのデータの貼り付け/読み取りを防止します。カットは単にコピーの後に削除が続くため、カットは有効になります。
  • [〜#〜] ie [〜#〜]の動作は、「危険な」貼り付けを有効にしますが、カットイベントを実行しないため、私には意味がありません。

document.queryCommandSupported メソッドを使用して、可能なコマンドを機能検出できます。

4
Jenny O'Reilly

通常のページでは実行できず、バックグラウンドページでのみ実行できます。

2
serg

document.execCommand('paste')を使用するにはclipboardRead権限を設定し、execCommand('copy')execCommand('cut')を使用するにはclipboardWrite権限を設定する必要があります。
それ以外の場合、権限は拒否され、何も起こりません。

詳細については、 this リンクを確認してください。

1
realkstrawn93

コンテンツを受信できるフォーカスを制御する必要があります...

JSのクリップボードに関するいくつかの例については、 http://www.geekpedia.com/tutorial126_Clipboard-cut-copy-and-paste-with-JavaScript.html を参照してください。
および http://help.dottoro.com/ljcvtcaw.php

Chrome拡張機能については コピー/貼り付けが機能しないChrome拡張機能

0
Yahia

同じことを自分で手作業で行うことで、ペーストを模倣できます。

  1. オプション:ユーザーが貼り付けようとしたときにトリガーします
  2. クリップボードの内容を取得します(ブラウザが提供するポップアップを介してユーザーからの許可が必要です)
  3. アクティブコントロールにコンテンツを挿入します
  4. オプション:実際の貼り付けでトリガーされるイベントをトリガーします(リスナーの利益のために)

最初にステップ2と3に焦点を当て、この例では、アクティブな要素がテキスト入力であるかどうかを確認します。その場合は、テキストボックスの強調表示されたコンテンツを置き換え、カーソルの位置を変更して、貼り付けをシミュレートします。

_function myPaste() {
  navigator.clipboard.readText()
    .then(clipText => {
      const el = document.activeElement;
      if (el.nodeName === 'INPUT') {
        const newCursorPos = el.selectionStart + clipText.length;
        el.value =
          el.value.substring(0, el.selectionStart) +
          clipText +
          el.value.substring(el.selectionEnd);
        el.setSelectionRange(newCursorPos, newCursorPos);
      }
    });
}
_

#1の場合、ユーザーの貼り付け試行をインターセプトするリスナーを追加します。

_addEventListener("paste", pasteHandler);

function pasteHandler(e) {
  e.preventDefault();
  myPaste();
}
_

#4の場合、これをel.setSelectionRange(newCursorPos, newCursorPos);の後に追加します。

_el.dispatchEvent(new Event('input'));
el.dispatchEvent(new Event('change'));
_

データバインディングに基づいてDOMを操作するリアクティブフレームワークを使用している場合は、次のDOMレンダリングが完了するまでカーソル位置の更新を延期する必要があることに注意してください。例えば:

_Vue.nextTick(() => {
  el.setSelectionRange(newCursorPos, newCursorPos);
});
_
0
MarredCheese