剪贴板操作 Clipboard API 使用教程

一、简介

浏览器允许 JavaScript 脚本读写剪贴板,自动复制或粘贴内容。

一般来说,脚本不应该改动用户的剪贴板,以免不符合用户的预期。但是,有些时候这样做确实能够带来方便,比如“一键复制”功能,用户点击一下按钮,指定的内容就自动进入剪贴板。

目前,一共有三种方法可以实现剪贴板操作。

  1. Document.execCommand()方法。
  2. 异步的 Clipboard API
  3. copy事件和paste事件。

二、Document.execCommand()方法(弃用)

已弃用: 不再推荐使用该特性。虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留。请尽量不要使用该特性,并更新现有的代码;参见本页面底部的兼容性表格以指导你作出决定。请注意,该特性随时可能无法正常工作。

1、语法

bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

该方法有三个参数:

  • 第一个参数:字符串类型,传入需要操作的命令。如:‘cut’,‘copy’,'paste’等等。
  • 第二个参数:布尔类型,是否展示用户界面,一般为 false。
  • 第三个参数:一些命令(例如 insertImage)需要额外的参数(insertImage 需要提供插入 image 的 url),默认为 null。

返回值是布尔类型,如果是 false 则表示操作不被支持或未被启用。
如:

2、复制操作

复制时,先选中文本,然后调用document.execCommand('copy'),选中的文本就会进入剪贴板。

const inputElement = document.querySelector('#input');
inputElement.select();
document.execCommand('copy');

注意,复制操作最好放在事件监听函数里面,由用户触发(比如用户点击按钮)。如果脚本自主执行,某些浏览器可能会报错。

3、粘贴操作

粘贴时,调用document.execCommand('paste'),就会将剪贴板里面的内容,输出到当前的焦点元素中。

const pasteText = document.querySelector('#output');
pasteText.focus();
document.execCommand('paste');

4、小结

Document.execCommand()方法虽然方便,但是有一些缺点。

首先,它只能将选中的内容复制到剪贴板,无法向剪贴板任意写入内容。

其次,它是同步操作,如果复制/粘贴大量数据,页面会出现卡顿。有些浏览器还会跳出提示框,要求用户许可,这时在用户做出选择前,页面会失去响应。

为了解决这些问题,浏览器厂商提出了异步的 Clipboard API

三、 异步 Clipboard API

剪贴板 Clipboard API 提供了响应剪贴板命令(剪切、复制和粘贴)与异步读写系统剪贴板的能力。从权限 Permissions API 获取权限之后,才能访问剪贴板内容;如果用户没有授予权限,则不允许读取或更改剪贴板内容。

只有在用户事先授予网站或应用对剪切板的访问许可之后,才能使用异步剪切板读写方法。许可操作必须通过取得权限 Permissions API 的 “clipboard-read” 和/或 “clipboard-write” 项获得

它的所有操作都是异步的,返回 Promise 对象,不会造成页面卡顿。而且,它可以将任意内容(比如图片)放入剪贴板。

系统剪贴板暴露于全局属性 Navigator.clipboard 之中。

theClipboard = navigator.clipboard;

返回一个用于访问系统剪切板的 Clipboard 对象。
用法:

navigator.clipboard.readText().then(
  clipText => document.querySelector(".cliptext").innerText = clipText);;

这个代码片段将 HTML 中拥有类名 “cliptext” 的第一个元素的内容替换为剪切板中的内容。这段代码可用于在浏览器拓展中定时自动更新或者由事件触发,实时显示当前剪切板上的内容。

如果剪切板为空,或者不包含文本,则 “cliptext” 元素的内容将被清空。这是因为在剪切板为空或者不包含文本时,readText() 会返回一个空字符串。

四、Clipboard对象

Clipboard 对象提供了四个方法,用来读写剪贴板。它们都是异步方法,返回 Promise 对象。
分别是:

  1. Clipboard.read()
  2. Clipboard.readText()
  3. Clipboard.write()
  4. Clipboard.writeText()

1、Clipboard.read()

Clipboard.read()方法用于复制剪贴板里面的数据,可以是文本数据,也可以是二进制数据(比如图片)。该方法需要用户明确给予授权许可。
返回的一个Promise对象,一旦该对象的状态变为 resolved,就可以获得一个数组,每个数组成员都是 ClipboardItem 对象的实例。
例如:

navigator.permissions.query({name: "clipboard-read"}).then(result => {
  // 先查询用户授权是否已经允许

  if (result.state == "granted" || result.state == "prompt") {
    navigator.clipboard.read().then(data => {
      for (let i=0; i<data.items.length; i++) {
        if (data.items[i].type != "text/plain") {
          alert("剪切板内容不是一个文本");
        } else {
          textElem.innerText = data.items[i].getAs("text/plain");
        }
      }
    });
  }
});

2、Clipboard.readText()

Clipboard.readText()方法用于复制剪贴板里面的文本数据。
要从剪贴板中读取非文本内容,请改用read()方法。您可以使用 writeText()将文本写入剪贴板。
例如:

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

这些需要用户操作才能触发。比如点击等等。

3、Clipboard.write()

Clipboard 的方法 write() 写入图片等任意的数据到剪贴板。这个方法可以用于实现剪切和复制的功能。
但是你要提前获取 “Permissions API” 的 “clipboard-write” 权限才能将数据写入到剪贴板。

语法:

var promise = navigator.clipboard.write(dataTransfer)

例如:

function setClipboard(text) {
  let data = new DataTransfer();

  data.items.add("text/plain", text);
  navigator.clipboard.write(data).then(function() {
    /* success */
  }, function() {
    /* failure */
  });
}

代码创建了一个 DataTransfer 对象,要替换的内容存储在这里。执行 DataTransferItemList.add() 将数据写入进去,然后执行 write() 方法,指定执行成功或错误的结果。

4、Clipboard.writeText()

Clipboard 接口的 writeText() 方法可以写入特定字符串到操作系统的剪切板。
语法:

var promise = navigator.clipboard.writeText(newClipText)

返回一个Promise ,一旦剪贴板的内容被更新,它就会被解析。如果调用者没有写入剪贴板的权限,则拒绝写入剪切板(reject)。
例如:

navigator.clipboard.writeText("<empty clipboard>").then(function() {
  /* clipboard successfully set */
}, function() {
  /* clipboard write failed */
});

五、cut事件,copy事件和paste事件

cut事件

进行剪切操作触发事件
例子:
html

<div class="source" contenteditable="true">Cut text from this box.</div>
<div class="target" contenteditable="true">And paste it into this one.</div>

JavaScript

const source = document.querySelector("div.source");

source.addEventListener("cut", (event) => {
  const selection = document.getSelection();
  event.clipboardData.setData("text/plain", selection.toString().toUpperCase());
  selection.deleteFromDocument();
  event.preventDefault();
});

cut事件则是在用户进行剪切操作时触发。从event.clipboardData中拿到数据。

copy事件

用户向剪贴板放入数据时,将触发copy事件。
html

<div class="source" contenteditable="true">Copy text from this box.</div>
<div class="target" contenteditable="true">And paste it into this one.</div>

JavaScript

const source = document.querySelector("div.source");

source.addEventListener("copy", (event) => {
  const selection = document.getSelection();
  event.clipboardData.setData("text/plain", selection.toString().toUpperCase());
  event.preventDefault();
});

paste事件

用户使用剪贴板数据,进行粘贴操作时,会触发paste事件。

<div class="source" contenteditable="true">Copy text from this box.</div>
<div class="target" contenteditable="true">And paste it into this one.</div>

JavaScript

const target = document.querySelector("div.target");

target.addEventListener("paste", (event) => {
  event.preventDefault();

  let paste = (event.clipboardData || window.clipboardData).getData("text");
  paste = paste.toUpperCase();
  const selection = window.getSelection();
  if (!selection.rangeCount) return;
  selection.deleteFromDocument();
  selection.getRangeAt(0).insertNode(document.createTextNode(paste));
  selection.collapseToEnd();
});

参考链接

Permissions_API
Clipboard API
Document.execCommand()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值