Clipboard Event

JavaScript

JavaScript 提供了 copy 事件,可以针对一般的复制动作进行一些额外的操作。比如,一些网站出于版本的考虑,可能会禁止拷贝;或者,一些网站允许拷贝,但是会希望在拷贝的内容后面加上一些版权的声明。这些操作,都可以通过 copy 事件进行处理。

举例来说,如果希望禁止网站上内容的拷贝,可以写:

window.addEventListener('copy', (event) => {
  event.preventDefault();
});

在上面的代码中,通过 event.preventDefault API 的调用,可以组织浏览器默认的复制行为。这样,即使用户进行了复制,实际上剪贴板也不会被更新。

第二个例子,假设希望在复制的内容后面加上额外的数据,可以写:

window.addEventListener('copy', (event) => {
  const selection = document.getSelection();
  const text = selection.toString();
  event.clipboardData.setData('text/plain', text + '\nExtra Text at Bottom');
  event.preventDefault();
});

需要注意几点:

  1. setData 的第一个参数是数据的格式,支持的类型可以参考 MDN,主要就是 MIME 类型,一般纯文本可以使用 text/plain
  2. 在调用 setData 之后,需要调用 event.preventDefault 才能保证设置成功,否则最终复制出来的依然是原始的文案

最后,需要说明的一点是:出于测试或者其他目的,JavaScript 也支持创建一个 ClipboardEvent 并发送给监听的元素,如:

window.addEventListener('copy', (event) => {
  console.log('copy event triggered');
  event.clipboardData.setData('text/plain', 'hello world');
  event.preventDefault();
});
const event = new ClipboardEvent('copy', { clipboardData: new DataTransfer() });
window.dispatchEvent(event);

那么,回调函数可以正常执行(Console 可以看到输出),但是 event 内尝试设置 Clipboard 的数据并不会成功。

总体上来说,浏览器端提供的 Copy 事件,只能获取/修改浏览器内发生的剪贴板复制操作;对于用户本身剪贴板操作内有的数据是无法读取的,在非用户触发的情况下,剪贴板的数据也是无法直接被修改的。

延伸阅读