10分钟搞懂“一键复制”

介绍

"一键复制"功能是前端开发中常见的功能需求之一,在链接复制、图片分享等场景下可以简化操作流程,极大的提升用户体验。

思路

在浏览器中,主要是利用 JavaScript 实现对剪贴板的写入和读取操作 ,来实现对内容的复制和粘贴。

方案

在页面中添加 input 和 button 这两个 DOM 元素

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" value="我是要被拷贝的文字" />
    <button>copy</button>
  </body>
</html>

所要达到的目的就是通过点击 copy 按钮可以将 input 中的内容写入到 剪切板 ,然后执行 粘贴(ctrl+v) 操作时可以将其内容写入到可输入的控件中去,下面是几种常见的实现方案:

1. document.execCommand

javascript 复制代码
const input = document.querySelector("input");
const button = document.querySelector("button");

button.addEventListener("click", () => {
  input.select();
  document.execCommand("copy");
});

通过 input.select() 选中 input 中的文本,接着执行 document.execCommand("copy") 将内容写入到剪切板,接着只要快速粘贴即可。

作为操作剪切板的传统方法,虽然使用简便,操作单一,但现阶段已被弃用 ,即使一些浏览器会出于 兼容性 的目的进行保留。

原因如下:

  1. 仅可将选中的数据进行 copy,无法便捷的写入自定义的内容
  2. 该方法输入 同步 操作,并且需要操作 DOM,在一定程度上会影响页面渲染和脚本执行
  3. 无需用户进行 授权,如果涉及敏感数据,可能存在极大的安全隐患

2. Clipboard API

该 API 被设计用来取代使用 document.execCommand() 的剪贴板访问方式,提供了响应剪贴板命令(剪切、复制和粘贴)与异步读写系统剪贴板的能力。从权限 Permissions API(en-US) 获取权限之后,才能访问剪贴板内容;如果用户没有授予权限,则不允许读取或更改剪贴板内容。

javascript 复制代码
const clipboard = navigator.clipboard

使用 navigator.clipboard 获取 clipboard Object ,如果值为 undefined,则说明浏览不支持。

如果想要往剪切板中写入内容,可以使用 writeText 方法

javascript 复制代码
const clipboard = navigator.clipboard;

if (!clipboard) {
  console.log("不支持");
  return
}

const button = document.querySelector("button");

button.addEventListener("click", async () => {
  try {
    await clipboard.writeText("自定义的文本内容");
    console.log("success");
  } catch (error) {
    console.log("failed", error);
  }
});

通过 clipboard.writeText 方法写入自定义的文本内容后执行粘贴操作即可。

如果想要粘贴剪切板中内容,可以使用 readText 方法

javascript 复制代码
const clipboard = navigator.clipboard;

if (!clipboard) {
  console.log("不支持");
  return
}

const button = document.querySelector("button");
button.addEventListener("click", async () => {
  try {
    const text = await clipboard.readText();
    console.log("success", text);
  } catch (error) {
    console.log("failed", error);
  }
});

假设事先已经通过 ctrl+v 拷贝过一些内容,或者说通过 writeText 方法写入过一些内容到剪切板,此时点击 copy 按钮,就会通过 clipboard.readText 读取剪切板的内容,如果是首次读取,则浏览器会弹出权限弹窗提醒用户进行授权,授权成功即可读取出剪切板中的内容并打印在控制台。

通过授权提示可以发现,clipboard 实际上也是支持读取和写入图片数据的,如果想要写入图片数据,需要使用 write 方法

javascript 复制代码
const clipboard = navigator.clipboard;

if (!clipboard) {
  console.log("不支持");
}

const button = document.querySelector("button");

button.addEventListener("click", async () => {
  try {
    const imgblob = await (
      await fetch("https://dummyimage.com/100.png")
    ).blob();
    await clipboard.write([
      new ClipboardItem({
        "image/png": imgblob,
      }),
    ]);
    console.log("success");
  } catch (error) {
    console.log("failed", error);
  }
});

代码还是比较简单的,拿到图片的 blob 对象之后,当作 new ClipboardItem 的参数进行传入再通过 write 写进剪切板,接着可以随便打开一个聊天软件执行粘贴操作即可。

如果说你想读取已经写入到剪切板中的图片数据,可以使用 read 方法

javascript 复制代码
const clipboard = navigator.clipboard;

if (!clipboard) {
  console.log("不支持");
}
const button = document.querySelector("button");

button.addEventListener("click", async () => {
  try {
    const imgblob = await (
      await fetch("https://dummyimage.com/100.png")
    ).blob();

    await clipboard.write([
      new ClipboardItem({
        "image/png": imgblob,
      }),
    ]);

    // 读取已经写入到剪切板中的数据
    const clipboardItemList = await clipboard.read();

    clipboardItemList.forEach((i) => {
      i.types.forEach(async (t) => {
        const iBlob = await i.getType(t);
        console.log("iBlob", iBlob);
      });
    });

    console.log("success", clipboardItemList);
  } catch (error) {
    console.log("failed", error);
  }
});

为了与 Google Chrome 浏览器保持一致,Firefox 只允许此函数处理 文本 、HTML 和 PNG 数据;在使用前需要检查 浏览器兼容性 和 剪切板可用性 以获取更多兼容性的信息。

可以看到,在 Clipboard API 的使用上,所有操作都返回了 Promise 对象,这意味着这些操作都是 异步 的;在 read 操作发生时,还会提示用户进行授权,否则会处理失败;除此之外,该功能仅在支持浏览器的安全上下文(HTTPS )中可用,开发环境(localhost)除外。

3. clipboard.js

cliboard.js 是一个轻量级的 clipboard 库,用于简化在网页中执行剪贴板操作的过程。

它提供了一种简单而强大的方式,让开发者能够通过点击按钮或其他交互方式,将文本内容复制到剪贴板,或从剪贴板中粘贴文本。

相关推荐
小码哥_常3 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
蜗牛攻城狮5 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
她说可以呀7 小时前
Vue插槽
前端·javascript·vue.js
qq_448011167 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan7 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
Yuzhiyuxia8 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展
2601_958352908 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝8 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing039 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel9 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端