web-dev-qa-db-fra.com

event.clipboardData.setData dans l'événement de copie

J'ai regardé de nombreux messages, mais je n'ai pas pu trouver de réponse claire et actuelle aux deux questions suivantes, car il semble que les normes et la prise en charge du navigateur aient constamment changé.

  1. Est-ce une opération légale selon la norme de changer le presse-papiers avec event.clipboardData.setData à l'intérieur d'un gestionnaire d'événement "copier"?

  2. Les dernières versions de Chrome/FF/Safari/IE/Chrome iOS/Android/iPhones le prennent-elles correctement en charge?

18
kofifus

Les API Clipboard étaient en effet en développement actif depuis 2016, mais les choses se sont stabilisées depuis:

L'utilisation de event.clipboardData.setData () est prise en charge

La modification du presse-papiers avec event.clipboardData.setData() dans un gestionnaire d'événements 'copy' Est autorisée par la spécification (tant que l'événement n'est pas synthétique ).

Notez que vous devez empêcher l'action par défaut dans le gestionnaire d'événements pour empêcher vos modifications d'être écrasées par le navigateur:

document.addEventListener('copy', function(e){
  e.clipboardData.setData('text/plain', 'foo');
  e.preventDefault(); // default behaviour is to copy any selected text
});

Pour déclencher l'événement de copie, utilisez execCommand

Si vous devez déclencher l'événement de copie (et pas seulement gérer les demandes de copie effectuées par l'utilisateur via l'interface utilisateur du navigateur), vous devez utiliser document.execCommand('copy'). Cela ne fonctionnera que dans certains gestionnaires, tels que le gestionnaire click:

document.getElementById("copyBtn").onclick = function() {
  document.execCommand('copy');
}

Les navigateurs modernes prennent en charge les deux méthodes

https://github.com/garykac/clipboard/blob/master/clipboard.md a une table de compatibilité pour execCommand(cut / copy / paste).

Vous pouvez tester cela en utilisant l'extrait ci-dessous, veuillez commenter avec les résultats.

Davantage de ressources

Cas de test

window.onload = function() {
  document.addEventListener('copy', function(e){
    console.log("copy handler");
    if (document.getElementById("enableHandler").checked) {
      e.clipboardData.setData('text/plain', 'Current time is ' + new Date());
      e.preventDefault(); // default behaviour is to copy any selected text
    }
    // This is just to simplify testing:
    setTimeout(function() {
      var tb = document.getElementById("target");
      tb.value = "";
      tb.focus();
    }, 0);
  });
  document.getElementById("execCopy").onclick = function() {
    document.execCommand('copy'); // only works in click handler or other user-triggered thread
  }
  document.getElementById("synthEvt").onclick = function() {
    var e = new ClipboardEvent("copy", {dataType: "text/plain", data:"bar"});
    document.dispatchEvent(e);
  }
}
<html>
<input id="enableHandler" type="checkbox" checked>
<label for="enableHandler">Run clipboardData.setData('text/plain', ...) in the "copy" handler</label>
<p>Try selecting this text and triggering a copy using</p>
<ul>
    <li><button id="execCopy">document.execCommand('copy')</button> - should work.</li>
    <li><button id="synthEvt">document.dispatchEvent(clipboardEvent)</button> - should NOT work</li>
    <li>with keyboard shortcut - should work</li>
    <li>or from the context menu - should work</li>
</ul>
<p>If the "copy" handler was triggered, the focus will move to the textbox below automatically, so that you can try pasting from clipboard:</p>
<input type="text" id="target" size="80">

L'API Async Clipboard fournira un moyen plus simple de gérer le presse-papiers

Une fois implémenté, navigator.clipboard vous permettra d'écrire du code comme ceci:

navigator.clipboard.writeText('Text to be copied')
  .then(() => {
    console.log('Text copied to clipboard');
  })
  .catch(err => {
    // This can happen if the user denies clipboard permissions:
    console.error('Could not copy text: ', err);
  });

Chrome 66 commence à expédier une implémentation partielle, et ils ont publié n article sur la nouvelle API .

38
Nickolay

Vous pouvez également le transformer en une fonction qui appelle son propre gestionnaire et le supprime

function copyStringToClipboard (string) {
    function handler (event){
        event.clipboardData.setData('text/plain', string);
        event.preventDefault();
        document.removeEventListener('copy', handler, true);
    }

    document.addEventListener('copy', handler, true);
    document.execCommand('copy');
}
13
Chad Scira

Liez l'ID d'élément à l'événement de copie, puis récupérez le texte sélectionné. Vous pouvez remplacer ou modifier le texte. Obtenez le presse-papiers et définissez le nouveau texte. Pour obtenir la mise en forme exacte, vous devez définir le type comme "text/hmtl". Vous pouvez également le lier au document au lieu de l'élément.

 $(ElementId).bind('copy', function(event) {
    var selectedText = window.getSelection().toString(); 
    selectedText = selectedText.replace(/\u200B/g, "");

    clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
    clipboardData.setData('text/html', selectedText);

    event.preventDefault();
  });
3
Sollymanul Islam