JS Async Copy 最优实现

117 阅读1分钟

讲解

视频链接: JavaScript Async Copy :https://v.douyin.com/iU5uwQ4b/

起因

  • 同事小伙伴 在执行 一个Copy 的时候无效
  • 具体场景:在调用接口 后去触发Copy 行为的时候异常
  • 在980ms 的时候 copy正常 在超过这个时间后Copy 无效

浏览器Copy API

  • document.execCommand(“Copy”)
  • Clipboard

第三方测试

分析: 在safari 浏览器中在异步调用接口超过980ms后就不能复制成功了



<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./clipboard.js"></script>
</head>

<body>
    <div class="btn"></div>
    <button>Copy</button>

</body>
<script>
    var clipboard = new ClipboardJS('.btn', {
            text: function (trigger) {
                return trigger.getAttribute('aria-label');
            },
        });

        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);
        });

    const t = document.querySelector('.btn');
    document.querySelector('button').addEventListener('click', async function () {

        //980ms 后复制异常
        await new Promise(reslove => setTimeout(reslove, 1000))
        t.setAttribute('aria-label', 'M-ddd')
        t.click();

        

    })
</script>

</html>

ClipBoard

  • 同步执行 延迟依然有980ms 规律 超过后复制失败
  • 所有问题都是问题。。。怎么解决

执行同步

  • navigator.clipboard.write  同步执行 异步响应

结论

  1. Copy 是可以在浏览器中。 进行异步的.
  2. Copy 函数必须立即执行 不能太多延迟等待。
  3. 如果非得考虑兼容性的话 (不能使用ClipboardItem), 只能使用copy 同步粘贴
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="btn"></div>
    <button>Copy</button>

</body>
<script>
 
    const coyp2 = (before, text) => {
        const type = "text/plain";

        const data = [new ClipboardItem({
            [type]: new Promise(async resolve => {

                await before();

                resolve(new Blob([text], { type }))
            })
        })];

        navigator.clipboard.write(data).then(
            () => {
                console.log("success");
            },
            () => {
                console.log("failure");
            },
        );
    }


 

    const t = document.querySelector('.btn');
    document.querySelector('button').addEventListener('click', async function () {

      

        coyp2(async () => {
            await new Promise(reslove => setTimeout(reslove, 2000))
        }, 'M-ddd--123123')

    })
</script>

</html>