为什么 document.execCommand("paste") 在 Google Chrome 中不起作用?

问题描述 投票:0回答:8

我的分机有问题。我想从剪贴板粘贴数据。

到目前为止,我已经得到了这个:

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

出现警报,但没有粘贴任何内容。

我有一种感觉,

document
部分需要改变,但我不知道该怎么做。有什么想法吗?

javascript google-chrome google-chrome-extension clipboard
8个回答
19
投票

出于安全考虑,“合理”的浏览器不支持调用

document.execCommand("paste")
,因为它可能使脚本能够从剪贴板读取敏感数据(如密码)。

这是关于剪贴板事件的document.execCommand("...")

兼容性矩阵

“复制” “粘贴” “切”
IE 好的 好的 n/a
边缘 好的 n/a 好的
火狐 好的 n/a 好的
好的 n/a 好的

我的两分钱:

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

document.queryCommandSupported 方法功能检测可能的命令。

编辑: 根据 MDN document.queryCommandSupported

 现已弃用,不应再使用。


18
投票
Chrome 中曾经有一个实验性的剪贴板 API,但在 Chrome 13 中被删除了。

Chrome 已转向更标准的

document.execCommand('paste')

document.execCommand('copy')
document.execCommand('cut')
 命令:

在 Chrome 中,您需要将权限添加到清单中:“clipboardRead”和“clipboardWrite”。

在 Chrome 38 之前,这些剪贴板权限仅适用于后台脚本等扩展页面。从 Chrome 39 开始,内容脚本在清单文件中声明剪贴板权限后也可以使用这些剪贴板 API。


8
投票
这对我来说在后台页面效果很好。

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);
    

2
投票
不能在普通页面执行,只能在后台页面执行。


1
投票
您需要一个能够接收内容的焦点控件...

有关 JS 中剪贴板的一些示例,请参阅

http://www.geekpedia.com/tutorial126_Clipboard-cut-copy-and-paste-with-JavaScript.html
http://help.dottoro.com/ljcvtcaw.php

有关 Chrome 扩展程序,请参阅

复制/粘贴在 Chrome 扩展程序中不起作用


1
投票
您需要设置

clipboardRead

权限才能使用
document.execCommand('paste')
,以及
clipboardWrite
权限才能使用
execCommand('copy')
execCommand('cut')
否则,权限将被拒绝并且不会发生任何事情。

查看

链接了解更多详情。


1
投票
您可以通过自己动手做同样的事情来模仿粘贴:

    可选:当用户尝试粘贴时触发
  1. 获取剪贴板的内容(需要通过浏览器提供的弹出窗口获得用户许可)
  2. 将内容插入活动控件
  3. 可选:触发真实粘贴会触发的事件(为了任何听众的利益)
首先关注步骤 #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
投票
因为在manifest v3上不支持serviceworker,经过长时间的研究,我找到了更好的解决方案:(你仍然需要在manifest中设置clipboardRead权限)

navigator.clipboard .readText() .then( (clipText) => console.log(clipText) );
    
© www.soinside.com 2019 - 2024. All rights reserved.