web-dev-qa-db-fra.com

document.execCommand ('copy') ne fonctionne pas sur Chrome

On Chrome only document.execCommand('copy') renvoie true mais ne copie pas le texte, il efface le presse-papiers.

Je ne trouve personne qui a eu le même problème, il y a beaucoup de questions similaires mais s'il vous plaît ne marquez pas cela comme un doublon à moins que ce ne soit vraiment le cas.

  • J'appelle selection.removeAllRanges() avant selection.addRange().
  • selection.getRangeAt(0).cloneContents() renvoie un fragment contenant le texte correct
  • Le texte dans la zone de texte n'apparaît pas sélectionné
  • Si j'appelle textarea.select() avant document.execCommand('copy') le texte apparaît sélectionné et est copié dans le presse-papiers. Je ne veux pas faire cela car cela concentre la zone de texte et fait défiler la page.
  • Testé sur Chrome 61 et 63, MacOS
  • Travailler dans Safari

Voici mon code (utilisé dans un écouteur d'événements de clic)
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'));
7
Jake

Je ne sais pas vraiment ce qui se passe vraiment ici ...

Il semble qu'il y ait une incompatibilité quant à ce qui devrait être utilisé entre les propriétés value et textContent de votre zone de texte.
Chrome semble toujours utiliser value, tandis que Firefox utilise 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>

Puisque chrome ne regarde pas la propriété textContent, Range # selectNodeContents ne sélectionnera rien sur ce navigateur ...

Cependant, vous pouvez utiliser Range # selectNode qui devrait retourner le même résultat dans ce cas et contournera le problème.

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

J'ai constaté que vous ne pouvez pas insérer dynamiquement un champ de saisie, insérer du texte, puis le copier dans le presse-papiers. J'ai pu copier du texte à partir d'une balise d'entrée existante.

0
voodoologic