【问题标题】:Copying to clipboard with document.execCommand('copy') fails with big texts使用 document.execCommand('copy') 复制到剪贴板失败并出现大文本
【发布时间】:2017-06-27 07:45:23
【问题描述】:

我正在使用隐藏文本区域来放置一些文本,选择它,然后使用 document.execCommand 将其复制到剪贴板。这通常有效,但当文本很大时会失败(返回 false)。在 Chrome v55 中,它似乎失败了大约 180K 个字符。

以这种方式复制的数据量是否有限制?普通的 Ctrl+C 似乎不受同样的限制。

注意:有人将此标记为可能与 Does document.execCommand('copy') have a size limitation? 重复。这可能是类似的问题,但是那个被标记为我不使用的特定框架,而且也没有得到回答。我相信我的问题更笼统,仍然具有相关性。

我附上代码供参考。

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

【问题讨论】:

标签: javascript dom clipboard


【解决方案1】:

与execCommand('copy') 调用本身相比,这个问题更多地与呈现此长文本所需的时间有关。

Firefox 提出了一个非常解释性的错误消息:

document.execCommand(‘cut’/‘copy’) 被拒绝,因为它不是从短期运行的用户生成的事件处理程序内部调用的。

您的代码生成文本的时间过长,因此浏览器无法将其识别为半可信事件...

然后解决方案是首先生成此文本,并且只有在听取用户手势后才能调用execCommand。所以为了使它成为可能,你可以例如监听mousedown事件生成文本,只有在mouseup事件中才会真正执行复制命令。

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2011-10-06
    • 1970-01-01
    • 2021-07-09
    相关资源
    最近更新 更多