document.execCommand()
传统方法,兼容性好,但已弃用。
问题是该方法只能复制选中的文本,就是说在复制前需要用到select将内容先选中。例
const inputElement = document.querySelector('#input');
inputElement.select();
document.execCommand('copy');
如果不是复制DOM元素里的内容,而是在JS中的任意文本.
要先创建一个元素,将要复制的值放进去,再选中、复制,最后记得要移除这个元素。例
export const copyStringToClipboard = (str: string) => {
const el = document.createElement('input');
el.value = str;
el.setAttribute('readonly', '');
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
};
还有一个问题是它是同步操作,如果数据量大,可能在操作时卡顿。所以现在推出了异步的Clipboard API。
Clipboard
const clipboardObj = navigator.clipboard;
Clipboard对象提供了四种异步方法,都是返回 Promise 对象。
read() 从剪贴板读取数据(比如图片)
readText() 从操作系统读取文本
write() 写入任意数据至操作系统剪贴板
writeText() 写入文本至操作系统剪贴板。
用writeText写了一个拷贝方法,既可以拷贝传入的任意字符串到剪贴板也可以根据传入的elemetID拷贝DOM元素里的文本,满足不同场景需求。
export const copyStringToClipboard = (str: string, copyElementId?: string) => {
if (copyElementId) { // 如果传入elemetID则拿到对应DOM的文本
const copyElement = document.getElementById(copyElementId);
str = copyElement.innerText;
}
const clipboardObj = navigator.clipboard;
if (clipboardObj) { // 不支持Clipboard对象直接报错
return clipboardObj.writeText(str).then( // 读取内容到剪贴板
() => message.success('Copied to clipboard'),
() => message.error('Failed to copy')
);
}
return message.error('Failed to copy');
};
参考
https://developer.mozilla.org/zh-CN/docs/Web/API/Clipboard
https://www.ruanyifeng.com/blog/2021/01/clipboard-api.html