Clipboard 复制功能
Clipboard API 是浏览器提供的原生接口,允许开发者以编程方式访问和操作剪贴板内容。它支持复制和粘贴文本、图片等多种数据类型,且不依赖 Flash 或其他框架,具有良好的兼容性和性能。
前置知识
- 安全性:剪贴板操作涉及用户隐私,需确保操作透明且获得用户授权。
- 错误处理:由于剪贴板操作可能失败,建议使用 try-catch 捕获异常并提供友好的错误提示。
- 兼容性处理:在不支持 Clipboard API 的浏览器中,可以使用 document.execCommand('copy')作为备用方案,但该方式已逐渐被淘汰。
1 Clipboard API
writeText(text):将指定的文本写入剪贴板。
async function copyText(text) {
try {
await navigator.clipboard.writeText(text);
console.log("文本已复制到剪贴板");
} catch (err) {
console.error("复制失败:", err);
}
}
readText():从剪贴板读取文本内容。
async function pasteText() {
try {
const text = await navigator.clipboard.readText();
console.log("剪贴板内容:", text);
} catch (err) {
console.error("读取失败:", err);
}
}
write(data):将任意类型的数据(如图片)写入剪贴板。
async function copyImage(imageBlob) {
try {
await navigator.clipboard.write([new ClipboardItem({ "image/png": imageBlob })]);
console.log("图片已复制到剪贴板");
} catch (err) {
console.error("复制失败:", err);
}
}
read():从剪贴板读取任意类型的数据。
async function pasteImage() {
try {
const clipboardItems = await navigator.clipboard.read();
for (const item of clipboardItems) {
if (item.types.includes("image/png")) {
const blob = await item.getType("image/png");
console.log("剪贴板中的图片:", blob);
}
}
} catch (err) {
console.error("读取失败:", err);
}
}
2 权限管理
Clipboard API 的操作通常需要用户授权。可以通过 navigator.permissions.query 方法检查是否有权限访问剪贴板:
async function checkClipboardPermission() {
const permission = await navigator.permissions.query({ name: "clipboard-write" });
if (permission.state === "granted") {
console.log("有权限访问剪贴板");
} else {
console.log("无权限访问剪贴板");
}
}
3 兼容性
Clipboard API 在现代浏览器中得到了广泛支持,但某些旧版本浏览器可能不支持。可以通过以下方式检测兼容性:
在不支持 Clipboard API 的浏览器中,可以使用 document.execCommand('copy')作为备用方案,但该方式已逐渐被淘汰。
// 复制功能
const handleCopy = (url) => {
if (!url) return proxy.$modal.msgWarning("请先选择游戏名称后复制");
// 检查线上部署环境
if (window.isSecureContext && navigator.clipboard) {
navigator.clipboard
.writeText(url)
.then(() => {
proxy.$modal.msgSuccess(`复制成功,已复制到粘贴板!`);
})
.catch((err) => {
console.error("无法复制文本: ", err);
});
} else {
// 非https等安全环境 需使用老方法 document.execCommand 官方随时会放弃
let textArea = document.createElement("textarea");
textArea.value = url;
textArea.style.position = "absolute";
textArea.style.opacity = 0;
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
return new Promise((res, rej) => {
// 执行复制命令并移除文本框
document.execCommand("copy") ? res() : rej();
textArea.remove();
proxy.$modal.msgSuccess(`复制成功,已复制到粘贴板!`);
});
}
};
洗尽铅华始见金,褪去浮华归本真
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2022-03-06 【Vue2.x 随笔】如何初始化/清空所有data响应式数据 + 单独清空data响应式中的指定部分