clipboard动态获取文本,实现异步复制

复制的功能项目中很常见,直接用js也很容易实现。不过得考虑到很多兼容性问题。现在也有很多工具可以实现直接复制,我在项目中常用的有:

1、copy-to-clipboard

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框,关闭后也不能成功实现复制。目前尚未找到解决方法。

2、react-copy-to-clipboard

import { CopyToClipboard } from 'react-copy-to-clipboard';

<CopyToClipboard text={'这里是复制文本'} onCopy={(text, result) => { console.log(result)}>
    <div>COPY</div>
</CopyToClipboard>

 

该UI组件基于copy-to-clipboard生成,使用起来如上图,很简单方便。

 

3、Clipboard.js

应该是最常用的复制工具了,实现了纯 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)
}

 

posted @ 2021-08-03 09:31  一口吃出个大胖子  阅读(1657)  评论(0编辑  收藏  举报