讲解
视频链接: JavaScript Async Copy :https://v.douyin.com/iU5uwQ4b/
起因
- 同事小伙伴 在执行 一个Copy 的时候无效
- 具体场景:在调用接口 后去触发Copy 行为的时候异常
- 在980ms 的时候 copy正常 在超过这个时间后Copy 无效
浏览器Copy API
- document.execCommand(“Copy”)
- Clipboard
第三方测试
- unpkg.com/clipboard@2… execCommand
- Chrome Success
- Safari Error (> 980 ms)
分析: 在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 同步执行 异步响应
结论
- Copy 是可以在浏览器中。 进行异步的.
- Copy 函数必须立即执行 不能太多延迟等待。
- 如果非得考虑兼容性的话 (不能使用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>