clipboard动态获取文本,实现异步复制
复制的功能项目中很常见,直接用js也很容易实现。不过得考虑到很多兼容性问题。现在也有很多工具可以实现直接复制,我在项目中常用的有:
import copy from 'copy-to-clipboard';
copy('这里是复制文本') && console.log('复制成功');
copy复制成功则直接返回true,否则返回false。
那么如果要实现异步,直接这样:
import React, { useState, useEffect, useRef } from "react"; const copyTextRef = useRef(null); const getCopyData = async (params) => { const res = await Request.getCopyData(params); if (res.ret === 0) { copy('这里是复制文本') && console.log('复制成功'); } } <Button size={'small'} radius="50%" type="primary" onClick={() => { getCopyData(params); }}>复制</Button>
这种方式通过测试,发现在pc上可以正常使用,移动端安卓机上面表现没有问题,但是在ios系统上出现了问题,弹出了一个alert框,关闭后也不能成功实现复制。目前尚未找到解决方法。
import { CopyToClipboard } from 'react-copy-to-clipboard';
<CopyToClipboard text={'这里是复制文本'} onCopy={(text, result) => { console.log(result)}>
<div>COPY</div>
</CopyToClipboard>
该UI组件基于copy-to-clipboard生成,使用起来如上图,很简单方便。
应该是最常用的复制工具了,实现了纯 JavaScript (无 Flash)的浏览器内容复制到系统剪贴板的功能,可以在浏览器和 Node 环境中使用。具体信息可以看文档了解。
这里只看下简单使用以及异步处理。
import React, { useState, useEffect, useRef } from "react";
import ClipboardJS from 'clipboard'; useEffect(() => { if (ClipboardJS.isSupported()) { const clipboard = new ClipboardJS('#copyId'); clipboard.on('success', function (e) { console.log('复制成功!') e.clearSelection(); }); clipboard.on('error', function (e) { console.log('复制失败!'); }); } else { console.log('该版本不支持'); } }, []); <div data-clipboard-text="这里是复制文本" id="copyId">复制</div>
那如何实现异步呢,如果当前页面只有一个复制按钮,可以考虑在刚进入页面就去获取复制值并存储下来,也能实现直接复制。
那如果有多个复制按钮,并且需要根据不同参数获取到复制的值呢?
我的做法是把点击获取复制内容的dom和存储复制内容的dom分开。点击获取到复制的内容后,再模拟点击事件去复制。下面是具体操作:
import React, { useState, useEffect, useRef } from "react";
import ClipboardJS from 'clipboard'; const [copyText, setCopyText] = useState<any>(''); const copyTextRef = useRef(null); useEffect(() => { if (ClipboardJS.isSupported()) { const clipboard = new ClipboardJS('#copyId'); clipboard.on('success', function (e) { console.log('复制成功!') e.clearSelection(); }); clipboard.on('error', function (e) { console.log('复制失败!'); }); } else { console.log('该版本不支持'); } }, []); const getCopyData= async (params) => { const res = await Request.getCopyData(params); // 请求接口,去获取要复制的内容 if (res.ret === 0) { setCopyText(res.data); setTimeout(() => { copyTextRef.current.click(); // 模拟点击事件,实现复制 }, 100) } } <Button onClick={() => {getCopyData(params)}}>复制</Button> <span style={{opacity: 0}} id="copyId" ref={copyTextRef} data-clipboard-text={copyText}></span>
以上实现方式已经经过多次测试,pc和移动端支持良好,ios和安卓都能兼容,尚未发现其他不能复制的问题。
4、这里再贴一个直接js实现的复制方式
const copyToClipboard = (value) => { const input = document.createElement('input') document.body.appendChild(input) value = value.toString() input.setAttribute('value', value) input.select() input.setSelectionRange(0, input.value.length) if (document.execCommand('copy')) { document.execCommand('copy') console.log("复制成功") } else { console.log('复制失败') } document.body.removeChild(input) }