与剪贴板交互
扩展程序中使用剪贴板正在从 Web API document.execCommand
方法(已弃用)过渡到 navigator.clipboard
方法。
注意:navigator.clipboard
API 是规范中最近添加的功能,可能尚未在所有浏览器中完全实现。本文介绍了一些限制,但在使用这些方法之前,请务必查看每个方法的兼容性表格,以确保 API 支持您的需求。
这两个 API 之间的区别在于 document.execCommand
这类似于键盘复制、剪切和粘贴操作 - 在网页和剪贴板之间交换数据 - 而 navigator.clipboard
将任意数据写入和读取到剪贴板。
navigator.clipboard
提供单独的方法来读取或写入
- 文本内容,使用
navigator.clipboard.readText()
和navigator.clipboard.writeText()
。 - 图像、富文本、HTML 和其他富媒体内容,使用
navigator.clipboard.read()
和navigator.clipboard.write()
。
但是,虽然 navigator.clipboard.readText()
和 navigator.clipboard.writeText()
在所有浏览器上都能正常工作,但 navigator.clipboard.read()
和 navigator.clipboard.write()
则不然。例如,在撰写本文时,Firefox 上的 navigator.clipboard.read()
和 navigator.clipboard.write()
尚未完全实现,因此要
- 使用图像,请使用
browser.clipboard.setImageData()
将图像写入剪贴板,并使用document.execCommand("paste")
将图像粘贴到网页。 - 将富媒体内容(例如 HTML、包含图像的富文本等)写入剪贴板,请使用
document.execCommand("copy")
或document.execCommand("cut")
。然后,使用navigator.clipboard.read()
(推荐)或document.execCommand("paste")
从剪贴板读取内容。
写入剪贴板
本节介绍将数据写入剪贴板的选项。
使用剪贴板 API
剪贴板 API 将扩展程序中的任意数据写入剪贴板。使用该 API 需要在 manifest.json
文件中获得 "clipboardRead"
或 "clipboardWrite"
权限。由于该 API 仅适用于 安全上下文,因此无法从在 http:
页面上运行的内容脚本中使用,只能在 https:
页面上使用。
对于页面脚本,需要使用 Web API navigator.permissions
请求 "clipboard-write"
权限。您可以使用 navigator.permissions.query()
检查该权限。
navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
if (result.state === "granted" || result.state === "prompt") {
/* write to the clipboard now */
}
});
注意:clipboard-write
权限名称在 Firefox 中不受支持,仅限 Chromium 浏览器。
此函数获取一个字符串并将其写入剪贴板
function updateClipboard(newClip) {
navigator.clipboard.writeText(newClip).then(
() => {
/* clipboard successfully set */
},
() => {
/* clipboard write failed */
},
);
}
使用 execCommand()
document.execCommand()
方法的 "cut"
和 "copy"
命令用于用所选材料替换剪贴板的内容。这些命令可以在用户操作的短暂事件处理程序(例如,点击处理程序)中使用,无需任何特殊权限。
例如,假设您有一个包含以下 HTML 的弹出窗口
<input id="input" type="text" /> <button id="copy">Copy</button>
要使 "copy"
按钮复制 <input>
元素的内容,您可以使用如下代码
function copy() {
let copyText = document.querySelector("#input");
copyText.select();
document.execCommand("copy");
}
document.querySelector("#copy").addEventListener("click", copy);
由于 execCommand()
调用位于点击事件处理程序内,因此您无需任何特殊权限。
但是,假设您从警报触发复制操作
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 规则。因此,要向 span
、div
或 p
标签添加“复制到剪贴板”按钮,您需要使用变通方法,例如将输入的位置设置为绝对位置并将其移出视口。
浏览器特定注意事项
剪贴板和其他相关的 API 正在快速发展,因此浏览器之间在工作方式上存在差异。
在 Chrome 中
- 即使在用户生成事件处理程序之外写入剪贴板,您也不需要
"clipboardWrite"
。
在 Firefox 中
有关更多信息,请参阅 浏览器兼容性表格。
从剪贴板读取
本节介绍从剪贴板读取或粘贴数据的选项。
使用剪贴板 API
剪贴板 API 的 navigator.clipboard.readText()
和 navigator.clipboard.read()
方法允许您在 安全上下文 中读取剪贴板中的任意文本或二进制数据。这使您可以访问剪贴板中的数据,而无需将其粘贴到可编辑元素中。
一旦您从 权限 API 获得了 "clipboard-read"
权限,就可以轻松地从剪贴板读取。例如,此代码片段从剪贴板获取文本,并用该文本替换 ID 为 "outbox"
的元素的内容。
navigator.clipboard
.readText()
.then((clipText) => (document.getElementById("outbox").innerText = clipText));
使用 execCommand()
要使用 document.execCommand("paste")
,您的扩展需要 "clipboardRead"
权限。即使您是在用户生成的事件处理程序(例如 click
或 keypress
)中使用 "paste"
命令,也同样如此。
考虑包含以下内容的 HTML
<textarea id="output"></textarea> <button id="paste">Paste</button>
要将 ID 为 "output"
的 <textarea>
元素的内容设置为剪贴板中的内容(当用户单击 "paste"
<button>
时),您可以使用以下代码
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 的浏览器中加载。