web-dev-qa-db-fra.com

Utiliser execCommand (Javascript) pour copier du texte masqué dans le presse-papier

J'essaie de copier dans le presse-papiers sans utiliser Flash. Je prévois de revenir à Flash avec l'utilisation de ZeroClipboard si le navigateur est incompatible avec l'approche javascript.

J'ai un écouteur onClick pour le bouton qui ressemble à:

$(buttonWhereActionWillBeTriggered).click(function(){ 
    var copyDiv = document.getElementById(inputContainingTextToBeCopied);
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
}

et un champ de saisie comme suit:

<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo"/>

Cela fonctionne actuellement comme prévu, mais la conception nécessite que le champ contenant le texte à copier soit invisible. J'ai essayé les deux réglages type="hidden" et style="display: none" qui n'ont pas réussi. Il en résulte que le bouton sélectionne la page entière et copie le contenu dans le presse-papier de l'utilisateur.
Je suis relativement confiant que la cause n’est pas basée sur un navigateur, mais seulement, je teste sur Chrome (Version 43.0.2357.134 (64 bits))) sur Mac OS X 10.10. .4.

Est-il possible de maintenir la fonctionnalité lorsque le <input> est visible tout en le masquant? ou sinon, un autre itinéraire que je peux prendre?


Je suis au courant de questions similaires, dont aucune ne résout mon problème, que ce soit d'être trop vieux, de ne pas utiliser JavaScript ou de ne pas correspondre au scénario en question. Voici une bonne réponse pour toute personne ayant des problèmes similaires, moins spécifiques.

34
Aaron Critchley

--Mise à jour--

Document.execCommand ()

[1] Avant Firefox 41, la fonctionnalité de presse-papiers devait être activée dans le fichier de préférences user.js. Voir Un bref guide sur préférences de Mozilla pour plus d'informations . Si la commande n'était pas prise en charge ou activée, execCommand générait une exception au lieu de renvoyer false. Dans Firefox 41 et les versions ultérieures, les fonctionnalités du Presse-papiers sont activées par défaut dans tout gestionnaire d'événements capable d'afficher une fenêtre (scripts semi-fiables). ).

Depuis Firefox version 41 Document.execCommand () fonctionne maintenant. Donc, plus besoin de recourir à un repli.


Puisque les navigateurs semblent se comporter différemment en ce qui concerne l'accès au presse-papiers, il m'a fallu un certain temps pour comprendre.

C'est assez similaire à votre solution, mais la différence est de créer un élément temporaire et de le remplir avec l'entrée value. De cette façon, nous pouvons conserver la propriété display de l'entrée sur none.

Il existe également une solution de contournement pour [~ # ~], à savoir [~ # ~] qui utilise window.clipboardData.

Firefox ne me laissait pas du tout accéder au presse-papiers. J'ai donc dû ajouter un Prompt pour permettre aux utilisateurs de copier manuellement la valeur d'entrée. Bien sûr, un Prompt est moche, mais vous pouvez simplement utiliser un modal comme window, qui ferait la même chose.

Puisque cela semble être une chose noueuse, je suis sur Win7 (64 bits) et testé dans

Chrome - Version 43.0.2357.134 m

IE - Version 11.0.9600.17914

et Firefox est hors de propos, car il ne me permettrait pas d'y accéder de toute façon.

var copyBtn   = $("#copy-btn"),
    input     = $("#copy-me");

function copyToClipboardFF(text) {
  window.Prompt ("Copy to clipboard: Ctrl C, Enter", text);
}

function copyToClipboard() {
  var success   = true,
      range     = document.createRange(),
      selection;

  // For IE.
  if (window.clipboardData) {
    window.clipboardData.setData("Text", input.val());        
  } else {
    // Create a temporary element off screen.
    var tmpElem = $('<div>');
    tmpElem.css({
      position: "absolute",
      left:     "-1000px",
      top:      "-1000px",
    });
    // Add the input value to the temp element.
    tmpElem.text(input.val());
    $("body").append(tmpElem);
    // Select temp element.
    range.selectNodeContents(tmpElem.get(0));
    selection = window.getSelection ();
    selection.removeAllRanges ();
    selection.addRange (range);
    // Lets copy.
    try { 
      success = document.execCommand ("copy", false, null);
    }
    catch (e) {
      copyToClipboardFF(input.val());
    }
    if (success) {
      alert ("The text is on the clipboard, try to paste it!");
      // remove temp element.
      tmpElem.remove();
    }
  }
}

copyBtn.on('click', copyToClipboard);
#copy-me {
    display:none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="Element To Be Copied" id="copy-me" value="foo loves bar"/>
<button id="copy-btn">Copy</button><br/><br/>
<textarea placeholder="paste here"></textarea>
29
DavidDomain

Voici ma solution qui n'utilise pas jQuery:

function setClipboard(value) {
    var tempInput = document.createElement("input");
    tempInput.style = "position: absolute; left: -1000px; top: -1000px";
    tempInput.value = value;
    document.body.appendChild(tempInput);
    tempInput.select();
    document.execCommand("copy");
    document.body.removeChild(tempInput);
}
<!DOCTYPE html>
<html>
<head>
<title>Set Clipboard</title>
</head>
<body>
    <button onclick="setClipboard('foo loves bar')">Set Clipboard</button>
</body>
</html>
61
Dan Stevens

Grâce à l’aide de @DavidDomain, j’ai trouvé une approche quelque peu maladroite mais fonctionnelle.

Tout d'abord, j'ai déplacé le mode de saisie hors de l'écran et modifié certaines propriétés, ce qui entraîne:

<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo" style="display:none; position: relative; left: -10000px;"/>

affichage: aucun n'a été ajouté après les modifications suivantes au js

Après cela, le commentaire de @Pokkanome m'a permis de modifier la fonction onClick comme suit:

$(buttonWhereActionWillBeTriggered).click(function(){ 
    var copyDiv = document.getElementById(inputContainingTextToBeCopied);
    copyDiv.style.display = 'block';
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
    copyDiv.style.display = 'none';
}

Je ne sais pas s'il est possible de copier à partir d'une div cachée en utilisant cette méthode, ce qui serait logique en termes de sécurité du navigateur, car donner un accès inconditionnel au presse-papiers sera quelque peu risqué. L’approche adoptée a cependant le même résultat.

16
Aaron Critchley

2019 - était toujours à la recherche d'une réponse sans écran.

Ce que j’ai fait, c’est d’abord de changer le champ de saisie de texte en type = "text", de copier le texte puis de le redéfinir en type = "hidden". Ça marche bien.

<input id="dummy" name="dummy" type="hidden">

<script>
var copyText = document.getElementById("dummy");
copyText.type = 'text';
copyText.select();
document.execCommand("copy");
copyText.type = 'hidden';
</script>
2
Rick

Ce qui fonctionne pour moi était:

<div>
  <a class="copyBtn">Copy</a>
  <input class="d-none" value="teste">
</div>

et:

$('.copyBtn').on('click', function(e) {
  e.preventDefault();
  var input = $(this).parent().find(".dirVal");
  $(input).removeClass("d-none");
  input.select();

  document.execCommand('copy');
  $(input).addClass("d-none");
  callNotify("Parabéns!", "Caminho copiado para área de transferência!", "success");
});
1
Douglas Lopes

Cette question est très ancienne, alors j’ai une NOUVELLE réponse moins ancienne.

L'utilisation de ce script peut copier vos données. c'est beaucoup plus petit que les anciens

Tout ce qu'il fait est de cacher votre entrée WAYYY du côté de l'écran, le rendant ainsi caché. Tout en gardant la possibilité de le copier (contrairement à l'utilisation de Display: None;)

function copyFunc() {
  var copyText = document.getElementById("copyInp");
  copyText.select();
  document.execCommand("copy"); //this function copies the text of the input with ID "copyInp"
}
<input type="text" value="StuffYaWantCopied" id="copyInp" style="position:absolute;left:-1000px;top:-1000px;">
  <a onclick="copyFunc()" style="cursor:cell;">
     Click here to Copy!
  </a>
1
Taylor Spark