Comment puis-je copier dans le bloc-notes en JavaScript?

Quelle est la meilleure façon de copier du texte dans le presse-papiers? (multi-navigateur)

j'ai essayé:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

mais dans Internet Explorer il donne une erreur de syntaxe. Dans Firefox, il est écrit unsafeWindow is not defined .

un joli truc sans flash: comment Trello accède-t-il au presse-papiers de l'utilisateur?

2739
demandé sur Donald Duck 2008-12-30 16:09:05

30 réponses

vue d'ensemble

il y a 3 API de navigateur primaire pour copier sur le presse-papiers:

  1. Async presse-papiers de l'API [navigator.clipboard.writeText]
    • partie textuelle disponible en Chrome 66 (mars 2018)
    • L'accès est asynchrone et utilise promesses JavaScript , peut être écrit de sorte que l'utilisateur de sécurité invite (si affiché) n'interrompez pas le JavaScript dans la page.
    • Le texte
    • peut être copié dans le presse-papiers directement à partir d'une variable.
    • supporté uniquement sur les pages servies sur HTTPS.
    • dans Chrome 66 pages dans les onglets actifs peut écrire au presse-papiers sans un invite de permissions.
  2. document.execCommand('copy')
    • la plupart des navigateurs le supportent à partir d'avril 2015 (Voir la prise en charge du navigateur ci-dessous).
    • accès est synchrone, c.-à-d. arrête JavaScript dans la page jusqu'à ce qu'il soit complet, y compris l'affichage et l'utilisateur interagissant avec toute invite de sécurité.
    • texte est lu à partir du DOM et placé sur le bloc-notes.
    • au cours des essais ~avril 2015, seul Internet Explorer a été noté comme affichant des messages d'autorisation pendant l'écriture au presse-papiers.
  3. annulation de l'événement de copie
    • voir la documentation de L'API de presse-papiers sur annulation de l'événement de copie .
    • vous permet de modifier ce qui apparaît sur le presse-papiers à partir de n'importe quel événement de copie, peut inclure d'autres formats de données autres que le texte simple.
    • non couvert ici car il ne répond pas directement à la question.

développement Général de notes

Ne pas attendez-vous à ce que les commandes liées au presse-papiers fonctionnent pendant que vous testez le code dans la console. En général, la page doit être active (API de presse-papiers Async) ou nécessite une interaction utilisateur (par exemple un clic utilisateur) pour permettre ( document.execCommand('copy') ) d'accéder au presse-papiers Voir ci-dessous pour plus de détails.

Async + Secours

en raison du niveau de prise en charge par le navigateur de la nouvelle API de bloc-notes Async, vous voudrez probablement revenir à la méthode document.execCommand('copy') pour obtenir un bon navigateur couverture.

voici un exemple simple:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
  
  </textarea>
</div>

notez que ce snippet ne fonctionne pas bien dans la prévisualisation embarquée de StackOverflow vous pouvez l'essayer ici: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

Async presse-papiers de l'API

notez qu'il est possible de" demander la permission " et de tester l'accès au presse-papiers via L'API permissions dans Chrome 66.

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand ("copier")

le reste de ce post va dans les nuances et les détails de l'API document.execCommand('copy') .

Prise En Charge Du Navigateur

le support en JavaScript "15191210920 document.execCommand('copy') 1519410920" le support a augmenté, voir les liens ci-dessous pour les mises à jour de navigateur:

Exemple Simple

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

exemple complexe: copier au bloc-notes sans afficher l'entrée

L'exemple simple ci-dessus fonctionne très bien s'il y a un élément textarea ou input visible à l'écran.

dans certains cas, vous pouvez copier du texte dans le presse-papiers sans afficher un élément input / textarea . Ceci est un exemple d'une façon de travailler autour de cela (essentiellement insérez l'élément, copiez au bloc-notes, supprimez l'élément):

Testé avec Google Chrome 44, Firefox 42.0a1 et IE 11.0.8600.17814.

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a flash,
  // so some of these are just precautions. However in IE the element
  // is visible whilst the popup box asking the user for permission for
  // the web page to copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
  
  </textarea>
</div>

Notes complémentaires

fonctionne seulement si l'utilisateur prend une action

tous les appels document.execCommand('copy') doivent avoir lieu en conséquence directe d'une action de l'utilisateur, par exemple le gestionnaire d'événements click. C'est une mesure pour empêcher de jouer avec le presse-papiers des Utilisateurs quand ils ne s'y attendent pas.

voir le Google Developers post here pour plus d'informations.

API Presse-papiers

Notez le brouillon complet de L'API de presse-papiers les spécifications peuvent être trouvées ici: https://w3c.github.io/clipboard-apis /

est-il pris en charge?

  • document.queryCommandSupported('copy') doit retourner true si la commande" est supportée par le navigateur".
  • et document.queryCommandEnabled('copy') retour true si le document.execCommand('copy') réussira si on l'appelle maintenant. Vérification pour s'assurer que la commande a été appelée à partir d'un thread initié par l'utilisateur et d'autres exigences sont rencontrer.

cependant, à titre d'exemple de problèmes de compatibilité de navigateur, Google Chrome d'avril à octobre 2015 n'a retourné true de document.queryCommandSupported('copy') que si la commande était appelée à partir d'un thread initié par l'utilisateur.

Note compatibilité détail ci-dessous.

Détail De La Compatibilité Du Navigateur

tandis qu'un simple appel à document.execCommand('copy') enveloppé dans un bloc try / catch appelé comme un résultat d'un clic d'utilisateur vous obtiendra l'utilisation la plus compatible la suivante a quelques réserves:

tout appel à document.execCommand , document.queryCommandSupported ou document.queryCommandEnabled doit être enveloppé dans un bloc try / catch .

différentes implémentations et versions de navigateur jettent différents types d'exceptions lorsqu'elles sont appelées au lieu de retourner false .

différentes implémentations de navigateur sont encore en évolution et le API de presse-papiers est toujours en projet, donc n'oubliez pas de faire vos tests.

1661
répondu Dean Taylor 2018-04-12 18:07:06

copie automatique au presse-papiers peut être dangereux, donc la plupart des navigateurs (sauf IE) le rendent très difficile. Personnellement, j'utilise le truc simple suivant:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

, L'utilisateur est présenté avec la zone d'invite, où le texte à copier est déjà sélectionné. Il suffit maintenant d'appuyer sur Ctrl + C et entrer (pour fermer la boîte) -- et voilà!

maintenant le l'opération de copie de bloc-notes est sûre, parce que l'utilisateur le fait manuellement (mais d'une manière assez simple). Bien sûr, fonctionne dans tous les navigateurs.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>
1204
répondu Jarek Milewski 2015-08-19 08:00:45

L'approche suivante fonctionne dans Chrome, Firefox, Internet Explorer et Edge, ainsi que dans les versions récentes de Safari (le support de copie a été ajouté dans la version 10 qui a été publiée en octobre 2016).

  • créez un textarea et réglez son contenu sur le texte que vous voulez copier dans le presse-papiers.
  • ajoute le texte au DOM.
  • sélectionnez le texte dans la zone de texte.
  • document D'appel.execCommand ("copy")
  • supprimer le texte du dom.

Note: vous ne verrez pas le textarea, car il est ajouté et supprimé dans la même invocation synchrone du code Javascript.

certaines choses à surveiller si vous mettez en œuvre vous-même:

  • pour des raisons de sécurité, cela ne peut être appelé que depuis un gestionnaire d'événements tel que click (tout comme avec l'ouverture de fenêtres).
  • IE affichera un dialogue de permission la première fois que le presse-papiers est mis à jour.
  • IE, et le Bord de défilement lorsque le textarea est concentré.
  • execCommand () peut lancer dans certains cas.
  • les nouvelles lignes et les onglets peuvent être avalés sauf si vous utilisez une textarea. (La plupart des articles semblent recommander l'utilisation d'un div)
  • le textarea sera visible pendant que la boîte de dialogue IE est affichée, vous avez besoin de le cacher, ou utiliser le spécifique IE clipboardData api.
  • dans IE les administrateurs système peuvent désactiver L'API presse-papiers.

la fonction ci-dessous doit traiter toutes les questions suivantes aussi proprement que possible. Merci de laisser un commentaire si vous constatez des problèmes ou avez des suggestions pour l'améliorer.

// Copies a string to the clipboard. Must be called from within an 
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, 
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
// default a prompt is shown the first time the clipboard is 
// used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // IE specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text); 

    } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in MS Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        } catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x /

207
répondu Greg Lowe 2016-11-28 04:22:52

si vous voulez une solution vraiment simple (prend moins de 5 minutes pour intégrer) et semble bon droit de la boîte, alors Clippy est une bonne alternative à certaines des solutions plus complexes.

trombine le trombone

il a été écrit par un co-fondateur de Github. Exemple de code d'intégration Flash ci-dessous:

<object 
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed 
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

N'oubliez pas de remplacer #{text} par le texte que vous devez copier, et #{bgcolor} par un couleur.

93
répondu Brent Matzelle 2017-06-05 19:37:57

la lecture et la modification du presse-papiers à partir d'une page Web soulèvent des préoccupations en matière de sécurité et de protection de la vie privée. Cependant, dans Internet Explorer, il est possible de le faire. J'ai trouvé ce exemple d'extrait :

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />
78
répondu bandi 2018-04-16 21:08:33

j'ai récemment écrit un post de blog technique sur ce même problème (je travaille chez Lucidchart et nous avons récemment fait une révision sur notre bloc-notes).

copier du texte en clair dans le presse-papiers est relativement simple, en supposant que vous voulez le faire pendant un événement de copie du système (l'utilisateur appuie sur Ctrl" 151990920 C ou utilise le menu du navigateur).

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

mettre du texte sur le bloc-notes pendant un événement de copie de système est beaucoup plus difficile. Il semble que certaines de ces autres réponses renvoient à des façons de le faire via Flash, qui est la seule façon de le faire à travers les navigateurs (pour autant que je comprenne).

à part cela, il y a certaines options sur une base navigateur par navigateur.

C'est le plus simple en IE, où vous pouvez accéder à l'objet clipboardData à tout moment à partir de JavaScript via:

window.clipboardData

(quand vous tentez de faire ceci en dehors d'un événement de couper, copier, ou coller, cependant, IE demandera à l'utilisateur d'accorder la permission de presse-papiers de l'application web.)

dans Chrome, vous pouvez créer une extension Chrome qui vous donnera permissions presse-papiers (c'est ce que nous faisons pour Lucidchart). Ensuite, pour les utilisateurs avec votre extension installée, vous aurez juste besoin de tirer vous-même l'événement système:

document.execCommand('copy');

on dirait que Firefox a quelque options qui permettent aux utilisateurs d'accorder des permissions à certains sites pour accéder au presse-papiers, mais je n'ai pas essayé l'un de ces personnellement.

65
répondu Richard Shurtz 2018-03-15 17:58:59

bloc-notes.js est un petit, Non flash, utilitaire qui permet de copier du texte ou des données html dans le presse-papiers. Il est très facile à utiliser, il suffit d'inclure l' .js et d'utiliser quelque chose comme ceci:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

bloc-notes.js est également sur GitHub

44
répondu a coder 2015-08-11 15:33:37

voici mon avis sur celui-là..

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input)
    return result;
 }
39
répondu nikksan 2018-04-23 11:37:59

ZeroClipboard est le meilleur de la croix-navigateur solution que j'ai trouvé:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

si vous avez besoin d'un support non flash pour iOS, vous n'avez qu'à ajouter un repli:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard

35
répondu Justin 2014-04-29 22:11:38

D'un des projets sur lesquels j'ai travaillé, un plugin jQuery copy-to-clipboard qui utilise la bibliothèque Zero Clipboard .

il est plus facile à utiliser que le plugin de bloc-notes natif Zero si vous êtes un gros utilisateur de jQuery.

25
répondu SteamDev 2012-03-08 20:16:07

j'ai trouvé la solution suivante:

sur le handler key down crée l'étiquette" pre". Nous définissons le contenu à copier sur cette balise, puis faisons une sélection sur cette balise et retournons true dans handler. Cela appelle le gestionnaire standard de chrome et copie le texte sélectionné.

et si vous avez besoin vous pouvez définir le délai pour la fonction de restauration de la sélection précédente. Ma mise en œuvre sur Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

Utilisation:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

Sur la pâte, il crée textarea et fonctionne de la même manière.

PS peut être cette solution peut être utilisée pour créer entièrement cross-browser solution sans flash. Ses travaux en FF et Chrome.

21
répondu Enyby 2013-10-11 03:44:56

les autres méthodes vont copier du texte en clair dans le presse-papiers. Pour copier HTML (c'est-à-dire que vous pouvez coller les résultats dans un éditeur WSIWYG), vous pouvez faire ce qui suit dans C'est-à-dire seulement . Ceci est fondamentalement différent des autres méthodes, car le navigateur sélectionne visiblement le contenu.

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   
19
répondu Chase Seibert 2008-12-30 14:33:38

depuis récemment Chrome 42+ et Firefox 41+ soutiennent maintenant le document .execCommand ("copier") "151960920 de la commande". J'ai donc créé un couple de fonctions pour la copie de cross browser à la capacité de bloc-notes en utilisant une combinaison de Tim Down's old answer et Google Developer's answer :

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE 
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } else if (window.getSelection && document.createRange) {
        // non-IE
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        } catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el) 

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with IE 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    } else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press CTRL+C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
	but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
	versions of Chrome feature detection does not work!
	See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>
18
répondu Jeff Baker 2018-03-15 22:46:16

à partir de Flash 10, vous ne pouvez copier sur presse-papiers que si l'action provient de l'interaction de l'utilisateur avec un objet Flash. ( Lire la section connexe de L'annonce D'Adobe Flash 10 )

la solution est d'exagérer un objet flash au-dessus du bouton Copier, ou quelque soit l'élément qui initie la copie. Zero Clipboard est actuellement la meilleure bibliothèque avec cette implémentation. Les développeurs Flash expérimentés peuvent juste vouloir faire leur propre bibliothèque.

12
répondu matthuhiggins 2011-10-04 16:23:18

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>
12
répondu Samuel Tees 2017-10-21 00:05:27

j'ai trouvé la solution suivante:

j'ai le texte dans une entrée cachée. Parce que setSelectionRange ne fonctionne pas sur les entrées cachées, j'ai changé temporairement le type en texte, j'ai copié le texte et je l'ai rendu à nouveau caché. Si vous voulez copier le texte d'un élément, vous pouvez le passer à la fonction et enregistrer son contenu dans la variable cible.

    jQuery('#copy').on('click', function () {
        copyToClipboard();
    });

    function copyToClipboard() {
        var target = jQuery('#hidden_text');

        // make it visible, so can be focused
        target.attr('type', 'text');
        target.focus();
        // select all the text
        target[0].setSelectionRange(0, target.val().length);

        // copy the selection
        var succeed;
        try {
            succeed = document.execCommand("copy");
        } catch (e) {
            succeed = false;
        }

        // hide input again
        target.attr('type', 'hidden');

        return succeed;
    }
11
répondu Vassilis Pallas 2017-01-18 13:56:37

j'ai rassemblé ce que je pense être le meilleur.

  • utilise le texte CSS pour éviter les exceptions dans IE par opposition au style directement.
  • Restaure la sélection si il y avait un
  • fixe en lecture seule pour que le clavier ne s'affiche pas sur les appareils mobiles
  • a une solution de contournement pour iOS de sorte qu'il fonctionne réellement comme il bloque normalement execCommand.

le voici:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    } else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    } catch (err) {
      return false;
    }
  };
})();
10
répondu Dominic 2018-04-26 15:27:53

dans les navigateurs autres que IE, vous devez utiliser un petit objet flash pour manipuler le presse-papiers, p.ex.

9
répondu Quog 2013-11-22 00:08:07

copier le texte D'une entrée HTML au presse-papiers

 
 function myFunction() {
  /* Get the text field */
   var copyText = document.getElementById("myInput");
 
   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");
 
   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 
 
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">
 
 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>
 

Note: la méthode document.execCommand() n'est pas supportée dans IE9 et antérieurement.

Source : W3Schools - Copier le Texte dans le presse-papiers

9
répondu Alexandru Sirbu 2018-02-11 10:54:22

Je l'utilise très bien ( sans jQuery ou tout autre cadre).

function copyToClp(txt){
    txt = document.createTextNode(txt);
    document.body.appendChild(txt);
    if (document.body.createTextRange) {
        var d = document.body.createTextRange();
        d.moveToElementText(txt);
        d.select();
        document.execCommand('copy');
    } else {
        var d = document.createRange();
        d.selectNodeContents(txt);
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(d);
        document.execCommand('copy');
        window.getSelection().removeAllRanges();
    }
    txt.remove();
} 

Avertissement

Les onglets

sont convertis en espaces (au moins en chrome).

9
répondu Peter Rader 2018-09-13 10:26:29

j'ai eu le même problème en construisant une grille d'édition personnalisée à partir (quelque chose comme Excel) et la compatibilité avec Excel. J'ai dû supporter la sélection de plusieurs cellules, la copie et le collage.

Solution: créer un textarea où vous insérerez des données pour l'utilisateur à copier (pour moi quand l'utilisateur sélectionne des cellules), mettre l'accent sur elle (par exemple, quand l'utilisateur appuie sur Ctrl ) et sélectionner le texte entier.

Ainsi, lorsque l'Utilisateur a frappé Ctrl + C il est copié les cellules qu'il a choisi. Après avoir simplement redimensionné le textarea à 1 pixel (Je n'ai pas testé s'il fonctionnerait sur display:none). Il fonctionne très bien sur tous les navigateurs, et c'est transparent pour l'utilisateur.

Collage-vous pouvez faire la même chose comme ceci (diffère sur votre cible) - garder l'accent sur les événements textarea et catch paste en utilisant onpaste (dans mon projet, j'utilise textareas dans les cellules pour éditer).

Je ne peux pas coller un exemple (projet commercial), mais vous avez eu l'idée.

7
répondu xiniu 2012-03-08 20:14:40

j'ai utilisé le presse-papiers.js

, nous pouvons l'obtenir sur npm

npm install clipboard --save

et aussi sur bower

bower install clipboard --save

Utilisation et des exemples sont à https://zenorocha.github.io/clipboard.js/

7
répondu CodecPM 2015-10-28 11:17:06

beaucoup de réponses déjà mais j'aime en ajouter une (jQuery). Fonctionne comme un charme sur n'importe quel navigateur, aussi mobiles ceux (c'est-à-dire invite sur la sécurité, mais quand vous acceptez cela fonctionne très bien).

function appCopyToClipBoard( sText )
{
 var oText = false,
     bResult = false;
 try
 {
  oText = document.createElement("textarea");
  $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
  oText.select();
  document.execCommand("Copy");
  bResult = true;
 } catch(e) {}

 $(oText).remove();
 return bResult;
}

dans votre code:

if( !appCopyToClipBoard( 'Hai there! This is copied to the clipboard.' ))
 { alert('Sorry, copy to clipboard failed.'); }
7
répondu Codebeat 2016-12-12 16:22:02

ceci est une extension de la réponse de @Chase, avec l'avantage que cela fonctionnera pour les éléments D'IMAGE et de TABLE, pas seulement des DIVs sur IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
6
répondu Oliver Bock 2011-08-12 08:17:32

j'ai trouvé une autre solution agréable LMCButton - petit flash animé croix bouton de navigateur. Une fonction JavaScript et un bouton swf. Options simples (légende, JavaScript personnalisé).

Link: Copier dans le presse-papiers LMCButton

6
répondu Denis 2013-01-28 02:52:23

c'est ma faute. Cela ne fonctionne que sous IE.

Voici encore une autre façon de copier le texte:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
5
répondu dvallejo 2014-09-10 21:30:54

ng-clip était la solution la plus simple pour AngularJS.

5
répondu Nikolay Melnikov 2014-11-16 01:28:09

pour copier un texte sélectionné ('texte à copier') dans votre presse-papiers, créez un Bookmarklet (bookmarklet du navigateur qui exécute Javsaccript) et exécutez-le (Cliquez dessus). Il créera une textarea temporaire.

Code de Github:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
5
répondu Mauro 2018-01-16 06:18:07

il semble que j'ai mal lu la question, mais pour référence, vous pouvez extraire une gamme du DOM (pas de presse-papiers; compatible avec tous les navigateurs modernes), et le combiner avec les événements oncopie et onpaste et onbeforepaste pour obtenir le comportement de presse-papiers. Voici le code pour y parvenir:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
4
répondu mrBorna 2011-08-17 14:49:18

autant que je sache cela ne fonctionne que dans Internet Explorer.

Voir aussi " Dynamic Tools - JavaScript Copy To Clipboard ", mais il faut d'abord que l'utilisateur change la configuration et même alors cela ne semble pas fonctionner.

4
répondu Stormenet 2012-03-08 20:05:13