10分钟搞懂“一键复制”

介绍

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

思路

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

方案

在页面中添加 inputbutton 这两个 DOM 元素

<!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>

0分钟搞懂“一键复制”"

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

1. document.execCommand

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) 获取权限之后,才能访问剪贴板内容;如果用户没有授予权限,则不允许读取或更改剪贴板内容。

const clipboard = navigator.clipboard

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

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

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 方法

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 读取剪切板的内容,如果是首次读取,则浏览器会弹出权限弹窗提醒用户进行授权,授权成功即可读取出剪切板中的内容并打印在控制台。

0分钟搞懂“一键复制”"

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

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 方法

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 只允许此函数处理 文本HTMLPNG 数据;在使用前需要检查 浏览器兼容性剪切板可用性 以获取更多兼容性的信息。

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

3. clipboard.js

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

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

0分钟搞懂“一键复制”"

原文链接:https://juejin.cn/post/7327686118887440396 作者:coderMonkey

(0)
上一篇 2024年1月25日 下午4:05
下一篇 2024年1月26日 上午10:00

相关推荐

发表回复

登录后才能评论