execCommand('copy')在Ajax/XHR回调中不起作用?

aeo*_*ant 8 html javascript ajax copy execcommand

(使用Chrome 44测试)

期望的行为:发出XHR请求,将结果放入文本区域,选择文本,然后复制到剪贴板.

实际行为:成功的XHR请求后,将结果放入文本区域并选择它,但无法将结果复制到剪贴板.但是,如果我在XHR回调之外启动副本,它就可以工作.

示例html页面:

var selectAndCopy = function() {
  // Select text
  var cutTextarea = document.querySelector('#textarea');
  cutTextarea.select();
  // Execute copy
  var successful = document.execCommand('copy');
  var msg = successful ? 'successful' : 'unsuccessful';
  console.log('Cutting text command was ' + msg);
};

var fetchCopyButton = document.querySelector('#fetch_copy');
fetchCopyButton.addEventListener('click', function(event) {
  var xhr = new XMLHttpRequest();
  xhr.open('get', 'http://httpbin.org/ip');
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // Set text
        var textarea = document.querySelector('#textarea');
        textarea.value = xhr.responseText;

        selectAndCopy();
      }
    }
  };
  xhr.send();
});

var copyButton = document.querySelector('#copy');
copyButton.addEventListener('click', function(event) {
  selectAndCopy();
});
Run Code Online (Sandbox Code Playgroud)
<html>

<head>
</head>

<body>
  <p>
    <textarea id="textarea">Hello, I'm some text!</textarea>
  </p>
  <p>
    <button id="fetch_copy">Fetch Data and Copy Textarea</button>
    <button id="copy">Copy Textarea</button>
  </p>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

如果按"获取数据并复制文本区域"按钮,则会成功提取数据但不会复制.如果按"复制文本区域"按钮,文本将按预期复制.我已经尝试了许多请求/复制组合来尝试让它工作但无济于事(包括在获取数据后以编程方式按下复制按钮).有谁知道这里发生了什么?这是安全功能还是什么?

我不希望用户必须按两个按钮来获取和复制(如果可能).

Tim*_*own 16

您只能直接响应受信任的用户操作(例如click事件)来触发系统剪贴板的副本.

规格:http://www.w3.org/TR/clipboard-apis/#integration-with-rich-text-editing-apis


Tre*_*vor 8

如果您使XMLHttpRequest同步,这将起作用.您只需false将第三个参数添加到xhr.open(...):

var selectAndCopy = function() {
  // Select text
  var cutTextarea = document.querySelector('#textarea');
  cutTextarea.select();
  // Execute copy
  var successful = document.execCommand('copy');
  var msg = successful ? 'successful' : 'unsuccessful';
  console.log('Cutting text command was ' + msg);
};

var fetchCopyButton = document.querySelector('#fetch_copy');
fetchCopyButton.addEventListener('click', function(event) {
  var xhr = new XMLHttpRequest();
  xhr.open('get', 'http://httpbin.org/ip', false);
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        // Set text
        var textarea = document.querySelector('#textarea');
        textarea.value = xhr.responseText;

        selectAndCopy();
      }
    }
  };
  xhr.send();
});

var copyButton = document.querySelector('#copy');
copyButton.addEventListener('click', function(event) {
  selectAndCopy();
});
Run Code Online (Sandbox Code Playgroud)
<html>

<head>
</head>

<body>
  <p>
    <textarea id="textarea">Hello, I'm some text!</textarea>
  </p>
  <p>
    <button id="fetch_copy">Fetch Data and Copy Textarea</button>
    <button id="copy">Copy Textarea</button>
  </p>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

  • 同步XHR通常是一个坏主意,但如果没有它,很难在一步中看到这样做的方法.此外,您还会在Chrome控制台中收到有关同步XHR请求的警告. (3认同)