Web开发中点击复制功能的三种实现方法
Web开发中点击复制功能的三种实现方法
在Web开发中,点击复制功能是一个常见的需求。本文将介绍三种实现该功能的方法:使用document.execCommand、Clipboard API以及第三方库clipboard.js。每种方法都有其特点和适用场景,读者可以根据实际需求选择合适的方法。
document.execCommand
document.execCommand('copy')
是早期在Web上实现复制功能的方法,现在已经被标记为废弃,但是在业务开发中还是会经常使用(个人感觉问题不大)。
兼容性
具体实现
function copyString(str: string) {
const input = document.createElement("input");
input.value = str;
input.style.opacity = "0";
document.body.appendChild(input);
input.select();
try {
const code = document.execCommand("copy");
if (code) {
console.log("复制成功");
} else {
console.log("复制失败");
}
} catch (e) {
console.log("复制失败");
}
document.body.removeChild(input);
}
步骤如下:
- 创建一个input元素
- 将要复制的值赋值给input的value
- 设置样式将其隐藏
- 添加到body上
- 调用document.execCommand('copy')方法复制
- 移除节点
Clipboard
既然document.execCommand('copy')
被废弃了,那么有没有什么替代方式呢?当然有,那就是Clipboard API,剪贴板Clipboard API提供了响应剪贴板命令(剪切、复制和粘贴)与异步读写系统剪贴板的能力。从权限Permissions API获取权限之后,才能访问剪贴板内容;如果用户没有授予权限,则不允许读取或更改剪贴板内容。该API被设计用来取代使用document.execCommand()的剪贴板访问方式。
兼容性
具体实现
async function copyStringByClipBoard(str: string) {
try {
await navigator.clipboard.writeText(str);
console.log("复制成功");
} catch (e) {
console.log("复制失败");
}
}
这个clipboard被放在navigator中,我们调用clipboard中的writeText方法去进行赋值,但是需要注意的是,这里这个方法返回的是一个promise。
这个Clipboard API还是很强大的,除了可以复制文本,还可以复制别的一些东西,需要调用write方法,这里就不展开了,有兴趣的小伙伴可以去看一下developer.mozilla.org/zh-CN/docs/…
clipboard.js
除了自己实现,我们还可以借助第三方库来帮助我们实现复制,那就是clipboard.js。
使用方法
安装
npm install clipboard --save
使用方法
// template
<div class="btn" data-clipboard-text="我是一个大帅哥">clipboard 点击复制</div>
// script
const 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);
});
clipboardJs这里利用了h5的数据属性,和dom进行强相关
原理
去看了一下clipboardjs,本质上用到的也是document.execCommand,这就是为什么我上面说个人觉得问题不大了……
/**
* Creates a fake textarea element with a value.
* @param {String} value
* @return {HTMLElement}
*/
export default function createFakeElement(value) {
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
const fakeElement = document.createElement('textarea');
// Prevent zooming on iOS
fakeElement.style.fontSize = '12pt';
// Reset box model
fakeElement.style.border = '0';
fakeElement.style.padding = '0';
fakeElement.style.margin = '0';
// Move element out of screen horizontally
fakeElement.style.position = 'absolute';
fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px';
// Move element to the same position vertically
let yPosition = window.pageYOffset || document.documentElement.scrollTop;
fakeElement.style.top = `${yPosition}px`;
fakeElement.setAttribute('readonly', '');
fakeElement.value = value;
return fakeElement;
}
/**
* Executes a given operation type.
* @param {String} type
* @return {Boolean}
*/
export default function command(type) {
try {
return document.execCommand(type);
} catch (err) {
return false;
}
}
总结
我们可以直接使用clipboardjs开源库去实现我们的点击复制功能,之后如果不兼容的话,我们更换库即可,现在压力给到了clipboardjs。