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

时间:2018-03-01 02:48:13

标签: javascript clipboard dom-events execcommand goo.gl

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

问题源于规范:

  

从document.execCommand()触发的复制命令只会影响真实剪贴板的内容,前提是从用户信任和触发的事件调度事件,或者实现配置为允许此事件。如何配置实现以允许对剪贴板的写访问超出了本规范的范围。

execCommand Unofficial W3C Spec

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

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

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

供参考,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)。

1 个答案:

答案 0 :(得分:3)

有两种解决方案可行,但两者都存在缺陷。只有当您的请求少于一个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', function(e) {

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

});

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