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

Jak*_*ake 7 javascript clipboard google-chrome

在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'));
Run Code Online (Sandbox Code Playgroud)

Cat*_*nor 24

对于在 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}`) })
Run Code Online (Sandbox Code Playgroud)

更多信息:

Mozilla 对两种剪贴板系统的讨论

谷歌对两种剪贴板系统的讨论

另一个关于剪贴板 API 的好讨论

我可以用吗

  • 谢谢你!我一直在到处寻找这个! (2认同)

Kai*_*ido 20

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

似乎在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);
}
Run Code Online (Sandbox Code Playgroud)
<button id="btn">Copy!</button>
<textarea>You can paste here

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

由于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);
  
})
Run Code Online (Sandbox Code Playgroud)
<button id="btn">copy</button>
<textarea>You can paste here</textarea>
Run Code Online (Sandbox Code Playgroud)

  • 真棒的答案!我不仅学习了`textContent`和`selectNode`,还了解了Stack Overflow片段. (3认同)
  • 如果您尝试使用display:none隐藏该元素,则不会在Chrome中复制... (2认同)