与剪贴板交互

扩展程序中使用剪贴板正在从 Web API document.execCommand 方法(已弃用)过渡到 navigator.clipboard 方法。

注意:navigator.clipboard API 是规范中最近添加的功能,可能尚未在所有浏览器中完全实现。本文介绍了一些限制,但在使用这些方法之前,请务必查看每个方法的兼容性表格,以确保 API 支持您的需求。

这两个 API 之间的区别在于 document.execCommand 这类似于键盘复制、剪切和粘贴操作 - 在网页和剪贴板之间交换数据 - 而 navigator.clipboard 将任意数据写入和读取到剪贴板。

navigator.clipboard 提供单独的方法来读取或写入

但是,虽然 navigator.clipboard.readText()navigator.clipboard.writeText() 在所有浏览器上都能正常工作,但 navigator.clipboard.read()navigator.clipboard.write() 则不然。例如,在撰写本文时,Firefox 上的 navigator.clipboard.read()navigator.clipboard.write() 尚未完全实现,因此要

写入剪贴板

本节介绍将数据写入剪贴板的选项。

使用剪贴板 API

剪贴板 API 将扩展程序中的任意数据写入剪贴板。使用该 API 需要在 manifest.json 文件中获得 "clipboardRead""clipboardWrite" 权限。由于该 API 仅适用于 安全上下文,因此无法从在 http: 页面上运行的内容脚本中使用,只能在 https: 页面上使用。

对于页面脚本,需要使用 Web API navigator.permissions 请求 "clipboard-write" 权限。您可以使用 navigator.permissions.query() 检查该权限。

js
navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
  if (result.state === "granted" || result.state === "prompt") {
    /* write to the clipboard now */
  }
});

注意:clipboard-write 权限名称在 Firefox 中不受支持,仅限 Chromium 浏览器。

此函数获取一个字符串并将其写入剪贴板

js
function updateClipboard(newClip) {
  navigator.clipboard.writeText(newClip).then(
    () => {
      /* clipboard successfully set */
    },
    () => {
      /* clipboard write failed */
    },
  );
}

使用 execCommand()

document.execCommand() 方法的 "cut""copy" 命令用于用所选材料替换剪贴板的内容。这些命令可以在用户操作的短暂事件处理程序(例如,点击处理程序)中使用,无需任何特殊权限。

例如,假设您有一个包含以下 HTML 的弹出窗口

html
<input id="input" type="text" /> <button id="copy">Copy</button>

要使 "copy" 按钮复制 <input> 元素的内容,您可以使用如下代码

js
function copy() {
  let copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copy);

由于 execCommand() 调用位于点击事件处理程序内,因此您无需任何特殊权限。

但是,假设您从警报触发复制操作

js
function copy() {
  let copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

browser.alarms.create({
  delayInMinutes: 0.1,
});

browser.alarms.onAlarm.addListener(copy);

根据浏览器,这可能无法正常工作。在 Firefox 上,它将无法工作,并且您会在控制台中看到类似以下的消息

document.execCommand('cut'/'copy') 被拒绝,因为它不是从短运行的用户生成事件处理程序中调用的。

要启用此用例,您需要请求 "clipboardWrite" 权限。因此:"clipboardWrite" 使您能够在用户操作的短暂事件处理程序之外写入剪贴板。

注意:document.execCommand() 不适用于 type="hidden" 的输入字段、具有 HTML5 属性 "hidden" 的输入字段或使用 "display: none;" 的任何匹配 CSS 规则。因此,要向 spandivp 标签添加“复制到剪贴板”按钮,您需要使用变通方法,例如将输入的位置设置为绝对位置并将其移出视口。

浏览器特定注意事项

剪贴板和其他相关的 API 正在快速发展,因此浏览器之间在工作方式上存在差异。

在 Chrome 中

  • 即使在用户生成事件处理程序之外写入剪贴板,您也不需要 "clipboardWrite"

在 Firefox 中

有关更多信息,请参阅 浏览器兼容性表格

从剪贴板读取

本节介绍从剪贴板读取或粘贴数据的选项。

使用剪贴板 API

剪贴板 API 的 navigator.clipboard.readText()navigator.clipboard.read() 方法允许您在 安全上下文 中读取剪贴板中的任意文本或二进制数据。这使您可以访问剪贴板中的数据,而无需将其粘贴到可编辑元素中。

一旦您从 权限 API 获得了 "clipboard-read" 权限,就可以轻松地从剪贴板读取。例如,此代码片段从剪贴板获取文本,并用该文本替换 ID 为 "outbox" 的元素的内容。

js
navigator.clipboard
  .readText()
  .then((clipText) => (document.getElementById("outbox").innerText = clipText));

使用 execCommand()

要使用 document.execCommand("paste"),您的扩展需要 "clipboardRead" 权限。即使您是在用户生成的事件处理程序(例如 clickkeypress)中使用 "paste" 命令,也同样如此。

考虑包含以下内容的 HTML

html
<textarea id="output"></textarea> <button id="paste">Paste</button>

要将 ID 为 "output"<textarea> 元素的内容设置为剪贴板中的内容(当用户单击 "paste" <button> 时),您可以使用以下代码

js
function paste() {
  let pasteText = document.querySelector("#output");
  pasteText.focus();
  document.execCommand("paste");
  console.log(pasteText.textContent);
}

document.querySelector("#paste").addEventListener("click", paste);

浏览器特定注意事项

Firefox 从 54 版本开始支持 "clipboardRead" 权限,但仅支持粘贴到 内容可编辑模式 中的元素,对于内容脚本,这仅适用于 <textarea>。对于后台脚本,任何元素都可以设置为内容可编辑模式。

浏览器兼容性

api.Clipboard

BCD 表格仅在启用 JavaScript 的浏览器中加载。

webextensions.api.clipboard

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅