Javascript 从web worker获取数据后,无法将数据设置为剪贴板

Javascript 从web worker获取数据后,无法将数据设置为剪贴板,javascript,copy,web-worker,Javascript,Copy,Web Worker,当触发复制事件(cmd+c)时,我们的应用程序需要调用并从web worker获取数据,然后将其设置为剪贴板 但在数据准备好之后,将数据设置到剪贴板似乎不起作用 async function process_copy(event) { let data = await get_data_from_worker(); console.log("DATA FROM WORKER: ", data); event.clipboa

当触发复制事件(cmd+c)时,我们的应用程序需要调用并从web worker获取数据,然后将其设置为剪贴板

但在数据准备好之后,将数据设置到剪贴板似乎不起作用

async function process_copy(event) {

        let data = await get_data_from_worker();

        console.log("DATA FROM WORKER: ", data);

        event.clipboardData.setData('text/plain', data);
        event.clipboardData.setData('text/html', data);

        event.preventDefault();
  }

      
 window.addEventListener('copy', process_copy.bind(this));

我需要的是将数据设置到剪贴板,因为来自web worker的数据可以使用

无法使用此命令的原因

document.execCommand('copy')

因为从web worker获取数据可能需要5秒以上的时间,而上述命令在这些情况下不起作用

以下是一个例子:

worker.js

onmessage = function(e) {
  postMessage('WORKER DATA');
}
index.html

<!DOCTYPE html>
<html>
<body>
  <script>
    window.onload = function() {

      const my_worker = new Worker("worker.js");
      let call_back;

      my_worker.onmessage = function(e) {
        if(call_back){
          call_back(e.data);
        }
        call_back = undefined;
      }

      function get_data_from_worker() {
        return new Promise(
          function(resolve, reject) {
            call_back = resolve;
            my_worker.postMessage("GET DATA");
          }
        )
      }

      async function process_copy(event) {
        let data = await get_data_from_worker();

        console.log("DATA FROM WORKER: ", data);

        event.clipboardData.setData('text/plain', data);
        event.clipboardData.setData('text/html', data);

        event.preventDefault();
      }

      
      window.addEventListener('copy', process_copy.bind(this));

    };
  </script>
</body>
</html>

window.onload=函数(){
const my_worker=new worker(“worker.js”);
让我们回电话吧;
my_worker.onmessage=函数(e){
如果(回电话){
回拨(如数据);
}
回调=未定义;
}
函数从\u worker()获取\u数据{
回报新的承诺(
功能(解析、拒绝){
回拨=解决;
my_worker.postMessage(“获取数据”);
}
)
}
异步函数进程\复制(事件){
let data=等待从_worker()获取_data_;
日志(“来自工作者的数据:”,数据);
event.clipboardData.setData('text/plain',data);
event.clipboardData.setData('text/html',data);
event.preventDefault();
}
window.addEventListener('copy',process_copy.bind(this));
};
用户触发复制事件后,它调用process_copy函数,并等待数据

从工作人员获取数据功能中,我创建了一个承诺,它将消息发送给网络工作人员,然后将解析存储在回拨中以供以后使用

当网络工作者收到消息时,它准备数据并通过postMessage方法发回

然后,回拨(在my\u worker.onmessage内)将返回web worker消息


之后,数据在过程\复制功能中准备就绪。但是我们无法将该数据设置为剪贴板。

您正确地识别了问题:您需要同步处理事件,以便能够覆盖其默认行为

您可以通过重新设计工作流来解决该问题

如果您的数据确实需要生成,那么您很可能需要用户点击两次:

  • 准备数据
  • 将数据复制到剪贴板
  • 你不需要实际处理他们的复制事件来设置数据,所以点击就可以了,但是点击是需要的,因为浏览器不会让我们在剪贴板中拷贝任何东西而不需要用户的手势,并且在5s之后大多数浏览器会考虑用户手势已经死了。

    btn.onclick=async(evt)=>{
    //从第一次单击开始,我们准备数据
    btn.disabled=true;
    btn.textContent=“请稍候”;
    //模拟等待工人
    等待等待(1000);
    const datatext=“数据为文本”;
    const datahtml=“数据为html”;
    //现在数据已经准备好了
    //我们等待第二次点击
    btn.disabled=false;
    btn.textContent=“复制到剪贴板”;
    btn.onclick=async(evt)=>{
    //我们准备处理点击事件
    //所以我们可以覆盖它的内容
    addEventListener(“复制”,evt=>{
    evt.preventDefault();
    evt.clipboardData.setData(“文本/普通”,datatext);
    setData(“text/html”,datahtml);
    },{once:true});
    //我们强制复制事件(我们不关心此处的内容)
    文件。执行命令(“副本”);
    删除();
    pastezone.classList.remove(“隐藏”);
    };
    };
    pastezone.addEventListener(“粘贴”,(evt)=>{
    log(“作为文本:”,evt.clipboardData.getData(“text/plain”);
    log(“作为html:,evt.clipboardData.getData(“text/html”);
    });
    函数等待(毫秒){
    返回新承诺((res)=>setTimeout(res,ms));
    }
    .hidden{display:none;}
    准备要复制的数据
    您可以粘贴到这里进行测试
    
    回答得很好。我刚刚在一个类似的问题上加了一个悬赏,我问你是否想看一看:。