问题描述:

(Tested using Chrome 44)

Desired behaviour: Make XHR request, put result in text area, select text, and copy to clipboard.

Actual behaviour: On successful XHR request, puts the result in text area and selects it, but fails to copy result to clipboard. But if I initiate the copy outside of the XHR callback, it works.

Example html page:

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();

});

<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>

网友答案:

You can only trigger a copy to the system clipboard in direct response to a trusted user action, such as a click event.

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

网友答案:

If you make the XMLHttpRequest synchronous, this will work. You just have to add false as the third parameter to 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();
});
<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>
相关阅读:
Top