繁体   English   中英

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

[英]Why is document.execCommand("paste") not working in Google Chrome?

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

到目前为止,我有这个:

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

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

我感觉是document部分需要更改,但我不知道该怎么做。 有任何想法吗?

出于安全考虑,“合理”浏览器不支持调用document.execCommand("paste") ,因为它可能使脚本能够从剪贴板读取敏感数据(如密码)。

这是关于剪贴板事件的document.execCommand("...")兼容性矩阵

“复制” “粘贴” “切”
IE 不适用
边缘 不适用
火狐 不适用
铬合金 不适用

我的两分钱:

  • EdgeFirefoxChrome的行为是“合理的”,因为它们阻止从剪贴板粘贴/读取数据。 它们确实启用了剪切,因为剪切只是一个副本,然后是删除。
  • IE的行为对我来说毫无意义,因为它启用了“有风险”的粘贴,但不执行剪切事件。

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

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

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 开始,在清单文件 ( crbug.com/395376 ) 中声明剪贴板权限后,内容脚本也可以使用这些剪贴板 API。

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

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

您不能在常规页面上执行它,只能在后台页面中执行。

您需要设置clipboardRead权限以使用document.execCommand('paste')clipboardWrite权限以使用execCommand('copy')execCommand('cut')
否则,权限将被拒绝,什么也不会发生。

查看链接了解更多详情。

您可以自己动手做同样的事情来模仿粘贴:

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

你需要一个能够接收内容的焦点控件......

有关 JS 中剪贴板的一些示例,请参阅http://www.geekpedia.com/tutorial126_Clipboard-cut-copy-and-paste-with-JavaScript.html
http://help.dottoro.com/ljcvtcaw.php

关于 Chrome 扩展程序,请参阅在 Chrome 扩展程序中复制/粘贴不起作用

因为在 manifest v3 上不支持 service worker,经过长时间的研究,我找到了一个更好的解决方案:(你仍然需要在 manifest 中设置 clipboardRead 权限)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM