Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying to clipboard with document.execCommand('copy') fails with big texts

I'm using a hidden text area to put some text, select it and then using document.execCommand to copy it to the clipboard. This usually works but fails (returns false) when the text is large. In Chrome v55, it seems to fail around 180K characters.

Is there a limit to the amount of data that can be copied this way? Normal Ctrl+C doesn't seem subject to the same limitations.

note: someone marked this as a possible duplicate of Does document.execCommand('copy') have a size limitation?. It might be similar question, but that one was tagged as a specific framework that I don't use and also, it wasn't answered. I believe my question is more general and still relevant.

I attach the code for reference.

      function copyTextToClipboard(text) {
        var textArea = document.createElement('textarea');
        textArea.style.position = 'fixed';
        textArea.style.top = 0;
        textArea.style.left = 0;
        textArea.style.width = '2em';
        textArea.style.height = '2em';
        textArea.style.padding = 0;
        textArea.style.border = 'none';
        textArea.style.outline = 'none';
        textArea.style.boxShadow = 'none';
        textArea.style.background = 'transparent';
        textArea.value = text;
        document.body.appendChild(textArea);
        textArea.select();
        try {
          var successful = document.execCommand('copy');
          var msg = successful ? 'successful' : 'unsuccessful';
          console.log('Copying text command was ' + msg);
        } catch (err) {
          console.log('Oops, unable to copy');
        }
        document.body.removeChild(textArea);
      }
like image 463
Pablo Varasa Avatar asked Jun 27 '17 07:06

Pablo Varasa


People also ask

What can I use instead of execCommand copy?

The replacement is the Clipboard API.

How do I copy text to clipboard?

Select the first item that you want to copy, and press CTRL+C. Continue copying items from the same or other files until you have collected all of the items that you want. The Office Clipboard can hold up to 24 items.


1 Answers

The problem has more to do with the time it takes to render this long text than the execCommand('copy') call itself.

Firefox raises an quite explanatory error message :

document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.

Your code takes too long to generate the text, and thus the browser doesn't recognizes it as an semi-trusted event...

The solution is then to generate this text first, and only after listen to an user-gesture to call execCommand. So to make it possible, you can e.g. listen to a mousedown event to generate the text, and only in the mouseup event will you really execute the copy command.

const text = ('some text a bit repetitive ' + Date.now()).repeat(50000);

function copyTextToClipboard(text) {
  // first we create the textArea
  var textArea = document.createElement('textarea');
  textArea.style.position = 'absolute';
  textArea.style.opacity = '0';
  textArea.value = text;
  document.body.appendChild(textArea);

  var execCopy = e => {   // triggered on mouseup
    textArea.select();
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
    document.body.removeChild(textArea);
  };
  // here the magic
  btn.addEventListener('mouseup', execCopy, {
    once: true 
  });
}
// triggered on mousedown
btn.onmousedown = e => copyTextToClipboard(text);
<button id="btn">copy some text in your clipboard</button>
<p>May struggle your browser a little bit, it's quite a long text... Please be patient</p>
like image 196
Kaiido Avatar answered Oct 22 '22 03:10

Kaiido