document.execCommand('copy')无法在Chrome上运行

时间:2017-12-19 02:22:38

标签: javascript google-chrome clipboard

仅限Chrome浏览器document.execCommand('copy')返回true但不复制文本,它会清除剪贴板。

我找不到有同样问题的人,有很多类似的问题,但请不要将其标记为副本,除非它确实存在。

  • 我在selection.removeAllRanges()之前致电selection.addRange()
  • selection.getRangeAt(0).cloneContents()返回包含正确文本的片段
  • textarea中的文字未显示为已选中
  • 如果我在textarea.select()之前致电document.execCommand('copy'),则文字会显示为已选中并显示在剪贴板上。我不想这样做,因为它会聚焦textarea并导致页面滚动。
  • 在Chrome 61和63,MacOS
  • 上测试过
  • 在Safari工作

这是我的代码(在点击事件监听器中使用)
https://codepen.io/jakecr/pen/XVXvKz

var textarea = document.createElement('textarea');
textarea.textContent = 'coppied text';
document.body.appendChild(textarea);

var selection = document.getSelection();
var range = document.createRange();
range.selectNodeContents(textarea);
selection.removeAllRanges();
selection.addRange(range);

// DOESN'T WORK WITHOUT THIS
// textarea.select();

console.log(selection.getRangeAt(0).cloneContents());
console.log('copy success', document.execCommand('copy'));

3 个答案:

答案 0 :(得分:15)

我不清楚这里到底发生了什么......

似乎与textarea的valuetextContent属性之间应该使用的内容不匹配。
Chrome似乎总是使用value,而Firefox则使用textContent

btn.onclick = e => {
  const txt = document.createElement('textarea');
  document.body.appendChild(txt);
  txt.value = 'from value'; // chrome uses this
  txt.textContent = 'from textContent'; // FF uses this
  var sel = getSelection();
  var range = document.createRange();
  range.selectNode(txt);
  sel.removeAllRanges();
  sel.addRange(range);
  if(document.execCommand('copy')){
    console.log('copied');
  }
  document.body.removeChild(txt);
}
<button id="btn">Copy!</button>
<textarea>You can paste here

</textarea>

由于Chrome不会查看textContent属性, Range#selectNodeContents 将在此浏览器中不选择任何内容...

但是,您可以使用 Range#selectNode ,在这种情况下应返回相同的结果,并解决此问题。

document.getElementById('btn').addEventListener('click', function(){
  var textarea = document.createElement('textarea');
  textarea.textContent = 'copied text';
  document.body.appendChild(textarea);

  var selection = document.getSelection();
  var range = document.createRange();
//  range.selectNodeContents(textarea);
  range.selectNode(textarea);
  selection.removeAllRanges();
  selection.addRange(range);

  console.log('copy success', document.execCommand('copy'));
  selection.removeAllRanges();

  document.body.removeChild(textarea);
  
})
<button id="btn">copy</button>
<textarea>You can paste here</textarea>

答案 1 :(得分:11)

对于在2020年阅读此问题的人来说,如果您在document.execCommand('copy')方面遇到问题,则可以尝试使用剪贴板API。

Mozilla

浏览器扩展可以通过两种方式与系统交互 剪贴板:Document.execCommand()方法和现代 异步剪贴板API。

现在每Mozilladocument.execCommand()也已过时:

该功能已过时。尽管在某些浏览器中仍然可以使用, 不建议使用它,因为可以随时将其删除。尝试 避免使用它。

使用剪贴板API,将文本写入剪贴板特别容易:

const textToCopy = 'Hello there!'
navigator.clipboard.writeText(textToCopy)
  .then(() => { alert(`Copied!`) })
  .catch((error) => { alert(`Copy failed! ${error}`) })

更多信息:

Mozilla's discussion of the two clipboard systems

Google's discussion of the two clipboard systems

Another good discussion of the Clipboard API

CanIUse

答案 2 :(得分:0)

我发现您无法动态插入输入字段,插入一些文本,然后将其复制到剪贴板。我能够从现有的输入标签复制文本。