Chrome 为什么document.execCommand(“paste”)在谷歌浏览器中不起作用?

goqiplq2  于 2022-12-06  发布在  Go
关注(0)|答案(8)|浏览(1620)

我的扩展有问题。我想从剪贴板粘贴数据。
到目前为止,我得到了这个:

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

出现警报,但未粘贴任何内容。
我觉得需要修改的是document部分,但我不知道该怎么做。有什么想法吗?

btxsgosb

btxsgosb1#

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中,您需要将权限添加到清单中:“剪贴板读取”和“剪贴板写入”。http://developer.chrome.com/extensions/declare_permissions.html
在Chrome 38之前,这些剪贴板权限只对后台脚本等扩展页面可用。从Chrome 39开始,内容脚本也可以在清单文件(crbug.com/395376)中声明剪贴板权限后使用这些剪贴板API。

x6yk4ghg

x6yk4ghg2#

“合理的”浏览器不支持调用document.execCommand("paste"),这是出于安全考虑,因为它可能会使脚本从剪贴板中读取敏感数据(如密码)。
这是document.execCommand("...")关于剪贴板事件的兼容性矩阵
| | “副本”|“粘贴”|“切割”|
| - -|- -|- -|- -|
|工业工程师| 好的|好的|不适用|
|边缘| 好的|不适用|好的|
|火狐浏览器| 好的|不适用|好的|
|**镀 chrome **| 好的|不适用|好的|
"我的意见是“

  • EdgeFirefoxChrome 的行为是“合理的”,因为它们阻止从剪贴板粘贴/阅读数据。它们确实启用了剪切,因为剪切只是复制后删除。
  • IE 的行为对我来说没有意义,因为它启用了“危险”粘贴,但不执行剪切事件。

您可以使用document.queryCommandSupported方法功能检测可能的命令。

**编辑:**根据MDN,document.queryCommandSupported现在已过时,不应再使用。

jdg4fx2g

jdg4fx2g3#

这对我在背景页中很有效。

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”权限,并且您必须使用消息传递将此信息返回到您的内容脚本:

内容.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));
    }
});

后台.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);
qyzbxkaa

qyzbxkaa4#

你不能在普通页面上执行它,只能在背景页面上执行。

k3bvogb1

k3bvogb15#

你需要一个焦点控件,它能够接收内容...
有关JS中剪贴板的一些示例,请参见http://www.geekpedia.com/tutorial126_Clipboard-cut-copy-and-paste-with-JavaScript.html
http://help.dottoro.com/ljcvtcaw.php之间的关系
关于Chrome扩展,请参阅Chrome扩展中的复制/粘贴不起作用

ma8fv8wu

ma8fv8wu6#

您需要设置clipboardRead权限才能使用document.execCommand('paste'),设置clipboardWrite权限才能使用execCommand('copy')execCommand('cut')
否则,权限将被拒绝,不会发生任何事情。
有关详细信息,请查看此链接。

szqfcxe2

szqfcxe27#

您可以通过手动执行相同的操作来模拟粘贴:
1.可选:在用户尝试粘贴时触发
1.获取剪贴板的内容(需要通过浏览器提供的弹出窗口获得用户的许可)
1.将内容插入活动控件
1.可选:触发真实的粘贴将触发的事件(对任何侦听器都有益)
首先关注步骤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的React式框架,则需要将光标位置更新推迟到下一次DOM呈现之后。例如:

Vue.nextTick(() => {
  el.setSelectionRange(newCursorPos, newCursorPos);
});
insrf1ej

insrf1ej8#

因为在manifest上v3不适用于service worker,经过长时间的研究,我找到了一个更好的解决方案:(您仍然需要在信息清单中设定clipboardRead权限)

navigator.clipboard
        .readText()
        .then(
            (clipText) => console.log(clipText)
        );

相关问题