在任何浏览器,都默认支持用户的复制粘贴操作,换句话说: 在浏览器运行的JavaScript默认支持读写剪贴板的内容。 之前遇到的一个需求,点击按钮,复制文本到剪贴板中。
由于之前没遇到过这种需求 ,在百度查了一下,浏览器提供的Api 可以很方便的实现,大致有以下几种:
1. document.execCommand() 方法
这种方式也是平常使用最多的,最传统的方法。而且兼容性很好, 各大浏览器都支持
MDN定义如下:
document暴露execCommand方法,该方法允许运行命令来操纵可编辑内容区域的元素。
// 语法:
bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
返回值是布尔值,如果是 false 则表示操作不被支持或未被启用。
它支持复制、剪切和粘贴这三个操作:
// 复制
document.execCommand('copy')
// 剪切
document.execCommand('cut')
// 粘贴
document.execCommand('paste')
// copy input
<input id="input" value="这是一段可以复制的文字">
// paste input
<input id="pasteInput" placeholder="可以粘贴文字到这里">
<button id="copy">复制文本</button>
<button id="paste">粘贴文本</button>
const button = document.querySelector('#copy');button.addEventListener('click', () => { const input = document.querySelector('#input');
input.select();
document.execCommand('copy');})
示例代码中:
当点击“复制文本” 按钮时,先选中输入框input里面的内容,然后将其复制到剪贴板,粘贴时,执行document.execCommand('paste')方法,就会将剪贴板里面的内容,输出到当前的焦点元素中。
const button = document.querySelector('#paste');
button.addEventListener('click', () => {
const input = document.querySelector('#pasteInput');
input.focus();
document.execCommand('paste');
})
优点: api简洁方便,满足大部分场景需求。
缺点:
它只能将选中的内容复制到剪贴板,无法向剪贴板任意写入内容
它是同步执行的,如果复制、粘贴大量数据,页面会出现卡顿,导致页面无法及时响应等情况
2. Clipboard
Clipboard API 是浏览器在 doucument.execCommand()基础上的升级,推出的更强大的API。并且它的所有操作都是异步的,返回 Promise 对象,不会造成页面卡顿。而且,它可以将任意内容(比如图片)放入剪贴板。
navigator.clipboard
navigator.clipboard属性返回一个新的 Clipboard 对象,所有操作都通过这个对象进行。如果navigator.clipboard属性返回undefined,就说明当前浏览器不支持这个 API。
由于用户可能把敏感数据(比如密码)放在剪贴板,允许脚本任意读取会产生安全风险,所以这个 API 的安全限制比较多。
注意:Chrome 浏览器规定,只有 HTTPS 协议的页面才能使用这个 API。不过,开发环境(
localhost)允许使用非加密协议。
在调用时,需要明确获得用户的许可。跟剪贴板有关的主要有两个权限,clipboard-read(“读权限”)和 clipboard-wirte(“写权限”),在执行写入剪贴板时,脚本可以自动完成,但是读取剪贴板时,浏览器会弹出一个对话框,询问用户是否同意读取。
Clipboard 对象
Clipboard 对象提供了四个方法,用来读写剪贴板。它们都是异步方法,返回 Promise 对象。
1. Clipboard.readText()
Clipboard.readText()方法用于复制剪贴板里面的文本数据
document.body.addEventListener(
'click',
async (e) => {
const text = await navigator.clipboard.readText();
console.log(text);
}
)
上面示例中,用户点击页面后,就会输出剪贴板里面的文本。注意,浏览器这时会跳出一个对话框,询问用户是否同意脚本读取剪贴板。如果用户不同意,代码会报错,导致无法继续向下执行。可以使用try……catch语句处理。
2. Clipboard.read()
Clipboard.read()方法用于复制剪贴板里面的文本数据,也可以是二进制数据(比如图片)。
该方法返回一个 Promise 对象。一旦该对象的状态变为 resolved,就可以获得一个数组,每个数组成员都是 ClipboardItem 对象的实例。
async function getClipboardContents() {
try {
const clipboardItems = await navigator.clipboard.read();
for (const clipboardItem of clipboardItems) {
for (const type of clipboardItem.types) {
const blob = await clipboardItem.getType(type);
console.log(URL.createObjectURL(blob));
}
}
} catch (err) {
console.error(err.name, err.message);
}
}
ClipboardItem 对象表示一个单独的剪贴项,每个剪贴项都拥有ClipboardItem.types属性和ClipboardItem.getType()方法。
ClipboardItem.types属性返回一个数组,里面的成员是该剪贴项可用的 MIME 类型,比如某个剪贴项可以用 HTML 格式粘贴,也可以用纯文本格式粘贴,那么它就有两个 MIME 类型(text/html和text/plain)。
ClipboardItem.getType(type)方法用于读取剪贴项的数据,返回一个 Promise 对象。该方法接受剪贴项的 MIME 类型作为参数,返回该类型的数据,该参数是必需的,否则会报错。
3. Clipboard.writeText()
Clipboard.writeText()方法用于将文本内容写入剪贴板。
document.body.addEventListener(
'click',
async (e) => {
await navigator.clipboard.writeText('一段文本内容')
}
)
4. Clipboard.write()
Clipboard.write()方法用于将任意数据写入剪贴板,可以是文本数据,也可以是二进制数据。
该方法接受一个 ClipboardItem 实例作为参数,表示写入剪贴板的数据。
try {
const imgURL = 'https://dummyimage.com/300.png';
const data = await fetch(imgURL);
const blob = await data.blob();
await navigator.clipboard.write([
new ClipboardItem({
[blob.type]: blob
})
]);
console.log('Image copied.');
} catch (err) {
console.error(err.name, err.message);
}
上面示例中,脚本向剪贴板写入了一张图片。注意,Chrome 浏览器目前只支持写入 PNG 格式的图片。
ClipboardItem()是浏览器原生提供的构造函数,用来生成ClipboardItem实例,它接受一个对象作为参数,该对象的键名是数据的 MIME 类型,键值就是数据本身。
3. clipboard.js
clipboard 是一个非常轻巧,简洁的第三方库,压缩后只有3kb,可以说是很小了。并且周下载量在百万左右。
为什么而使用?
官方是这么说的:
如何安装?
npm安装 npm install clipboard --save 或 直接下载该文件到本地,下载地址:点我。
在项目中引用:
<script src="dist/clipboard.min.js"></script>
或者
import Clipboard from 'clipboard';
假如要复制input标签的内容, 可以这样写:
<input id="input" value="复制文本">
<button class="btn" data-clipboard-target="#input">点我复制</button>
import Clipboard from 'clipboard';
const btnCopy = new Clipboard('btn');
可以看到,在 <button> 标签中添加了一个 data-clipboard-target 属性,它的值是需要复制的 <input> 内容的 id。
事件
在复制事件后,有提供回调函数, 例如:
var clipboard = new ClipboardJS('.btn');
clipboard.on('success', function(e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
小结
目前遇到的只总结了这三种方法,clipboard js 具体参考官网demo,这里主要讲述有哪些方法可以实现此功能。