javascript – 如何创建一个获取外部资源的按钮并将其复制到剪贴板?

所以我有一个按钮,它应该创建一个奇特的共享URL,使用goo.gl缩短它,然后将其复制到剪贴板.好消息是,我已经成功完成了所有这些,但并非一下子全部完成.

问题源于规范:

Copy commands triggered from document.execCommand() will only affect the contents of the real clipboard if the event is dispatched from an event that is trusted and triggered by the user,or if the implementation is configured to allow this. How implementations can be configured to allow write access to the clipboard is outside the scope of this specification.

execCommand Unofficial W3C Spec

所以看起来这可能不起作用……

你看,为了缩短URL,我需要进行一次AJAX调用.我只在用户点击分享按钮时才这样做,因为我每天有1,000,000个限制缩短(如果我每次更改页面时都生成一个新的共享URL,那么一个用户很容易就会有1,000个新的URL,所以我’ d限制为最多1,000个最终用户:不是最佳选择).但这意味着我必须从发起事件的线程之外的线程中侦听AJAX事件,从而有效地失去了execCommand(‘copy’)所需的这种祝福状态.

有没有办法让一个单一的按钮同时生成goo.gl URL,然后将所说的短URL复制到剪贴板?

供参考,here’s what I wrote (Kotlin/JS)here’s the JavaScript output.
这是a SSCCE that illustrates how it seems like it should work,but does not(基于陈杨华’s answer).

最佳答案
有两种解决方案可行,但两者都存在缺陷.只有当您的请求少于一个seconde且其中一个被弃用时才有效,因此不应在生产环境中使用它.

第一个是使用setTimeout,它是少数几个不会丢失execCommand“特权”的异步函数之一.但它没有失去被认为是等于或小于1000毫秒.因此,如果您的请求少于此,那么您很高兴,但如果没有,那么您就会出错.如果将它与某种超时处理相结合,它可以工作,但如果请求通常需要超过1秒,那么它可能不够好.像这样例如:

var toCopy;

const buttonClick = () => {

  setTimeout(function() {
    if (toCopy) {
      // strangely,this execCommand will work
      console.log(document.execCommand('copy'));
    }
  },1000);

  var client = new XMLHttpRequest();
  client.onload = function(data) {

    toCopy = this.responseText;

  };

  // by setting your timeout on your request 
  // with the same duration as the setTiemout
  // you make sure it either works or throws an error
  client.ontimeout = function(data) {

    console.log('timeout');

  };
  client.timeout = 1000;
  client.open("GET","https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain");
  client.send();


}

$(() => {
  $("button").click(buttonClick)
})

document.addEventListener('copy',function(e) {

  e.preventDefault();
  e.clipboardData.setData('text/plain',toCopy);

});

https://jsfiddle.net/8md4Ltu2/4/

还有另一种方法可以使它工作,但它已被弃用,因此不能使用.但是,为了彻底,我会把它放在这里.您可以将XMLHttpRequest的异步标志设置为false.请求将是同步的,因此execCommand的处理非常简单.但是这个同步标志已被弃用,如果你试图使用它,那么指南是抛出一个错误,因此不能使用它.见:https://xhr.spec.whatwg.org/#synchronous-flag

var toCopy;

const buttonClick = () => {

  var client = new XMLHttpRequest();
  client.onload = function(data) {
    toCopy = this.responseText;
    console.log(document.execCommand('copy'));
  };


  client.open("GET","https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain",false);
  client.send();


}

$(() => {
  $("button").click(buttonClick)
})

document.addEventListener('copy',toCopy);

});

https://jsfiddle.net/zezskm2x/2/

相关文章

阅读本文之前,分享大家一张图片,看图会发现JavaScript开发...
Promises是一种关于异步编程的规范,目的是将异步处理对象和...
引子 Patrick Catanzariti 是一名Web开发工程师,最近他在 s...
小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了Java...
微软于今日(2015年12月10日)宣布即将开源Chakra核心控件,...
通过统计数据库中的1000多个项目,我们发现在 JavaScript 中...